Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
degiro-api
Advanced tools
Unofficial DeGiro API for Javascript. Buy and sell in the stock market. See your portfolio and much more
This is an unofficial TypeScript API client (Backend & Frontend) for DeGiro's trading platform. Using this module you can easily automate your orders (buy and sell) and get information about orders, funds or products.
All responses and objects are typed to develop faster and secure.
Be careful, DeGiro could block your account if they catch you using automation scripts
# using npm
npm install --save degiro-api
# using yarn
yarn add degiro-api
Basic log into DeGiro Platform. All endpoint needs a session key before those can be call them. You can pass credentials to DeGiro constructor or export in your terminal prompt sesion as DEGIRO_USER
and DEGIRO_PWD
const DeGiro = require('degiro-api').default
// or
import DeGiro from 'degiro-api'
// Basic degiro init
const degiro = new DeGiro({
username: '<your_username_here>',
pwd: '*****'
})
// or creating with the static create method
const degiro = DeGiro.create({ username: '*****', pwd: '*****' })
// or create with env credentials
const degiro = new DeGiro() // <-- Use DEGIRO_USER & DEGIRO_PWD
Inside all module are call to one debug function that listen the DEGIRO_DEBUG
env variable. Setting it with any truthy value you can enable all logs to debug the code.
$ export DEGIRO_DEBUG=1
$ yarn start
Run the next command and open index.html file inside doc folder to see a fresh documentation of the module.
Generate the documentation is easy, only run the next command:
$ yarn doc
or
$ npm run doc
Before run the test set you must set DEGIRO_USER & DEGIRO_PWD env export variables to attach an account to the test sets.
Be careful, the test set are going to make many request to degiro and are going to generate many session. DeGiro can track this events and ban your account (I don't know, read all contract before sign up 🤷♂️)
Now, I'm developing a feature that can bring you the ability of reuse only one session across all the entire test set. (The login and logout tests always are going to create differents sessions)
To run this experimental feature set the DEGIRO_TESTS_REUSE_SESSION
env variable to any truthy value.
Keep in mind: the tests can fail, if the deleteOrder test crash, you could have one new order in your account that you didn't create yourself. In those cases, the test process print this information in console. Read always all tests results.
To run all tests set run the command: yarn test
or npm run test
The JSessionId is the session browser cookie that DeGiro use to authenticate requests. You could prevent masive login/logout requests reusing a valid jsessionid from previous DeGiro instance. The way to do that is:
import DeGiro from 'degiro-api'
(async () => {
const degiro = new DeGiro({}) // <-- Using ENV variables
await degiro.login()
// Get the jsessionId (LOOK, is not a promise)
const jsessionId = degiro.getJSESSIONID()
})()
import DeGiro from 'degiro-api'
(async () => {
// Create an instance from a previous session
const degiro = new DeGiro({
username: '<your_username_here>',
pwd: '*******',
jsessionId: previousJSESSIONID
})
// Hydrate
// Re-use sessions need to re-hydrate the account config data and could use as a session expiration checker
await degiro.login()
// Do your stuff here...
})()
import DeGiro from 'degiro-api'
(async () => {
// Create an instance from a previous session
const degiro = new DeGiro({}) // <-- Using ENV variables
if (!degiro.isLogin()) {
await degiro.login()
if (degiro.isLogin()) {
// AWESOME!! We're in
}
}
})()
The problem with this method is that it only checks if you have the account configuration data set. The only way to verify that the session is still active is make a request.
You can force isLogin method passing it a secure
field set to true. This way the method will return a promise and below it will call a DeGiro API endpoint (usually getAccountConfig)
import DeGiro from 'degiro-api'
(async () => {
// Create an instance from a previous session
const degiro = new DeGiro({}) // <-- Using ENV variables
// Force to make a request and check if session is still alive
if(! await degiro.isLogin({ secure: true })) {
await degiro.login()
}
})()
login(): Promise<AccountDataType>
import DeGiro from 'degiro-api'
const degiro = new DeGiro({})
const accountData = await degiro.login()
logout(): Promise<void>
import DeGiro from 'degiro-api'
const degiro = new DeGiro({})
const accountData = await degiro.login()
await degiro.logout()
isLogin() (options?: IsLoginOptionsType): boolean | Promise<boolean>
import DeGiro from 'degiro-api'
const degiro = new DeGiro({})
await degiro.login()
const isLogin = degiro.isLogin()
if (! await degiro.isLogin({ secure: true })) {
// Do your magic
}
getJSESSIONID(): string | undefined
import DeGiro from 'degiro-api'
const degiro = new DeGiro({})
degiro.getJSESSIONID() // undefined
await degiro.login()
degiro.getJSESSIONID() // string
getAccountConfig(sessionId: string): Promise<AccountConfigType>
import DeGiro from 'degiro-api'
const degiro = new DeGiro({})
await degiro.login()
const accountConfig = await degiro.getAccountConfig()
console.log(accountConfig)
getAccountData(): Promise<AccountDataType>
import DeGiro from 'degiro-api'
const degiro = new DeGiro({})
await degiro.login() // Login also returns accountData
const accountData = await degiro.getAccountData()
console.log(accountData)
getAccountState(options: GetAccountStateOptionsType): Promise<any[]>
import DeGiro from 'degiro-api'
const degiro = new DeGiro({})
await degiro.login()
const accountState = await degiro.getAccountState()
console.log(accountState)
getAccountReports(): Promise<AccountReportsType>
import DeGiro from 'degiro-api'
const degiro = new DeGiro({})
await degiro.login()
const reports = await degiro.getAccountReports()
console.log(reports)
getAccountInfo(): Promise<AccountInfoType>
import DeGiro from 'degiro-api'
const degiro = new DeGiro({})
await degiro.login()
const accountInfo = await degiro.getAccountInfo()
console.log(accountInfo)
searchProduct(options: SearchProductOptionsType): Promise<SearchProductResultType[]>
DeGiroProducTypes
Search the text "AAPL" without any limitation
import DeGiro from 'degiro-api'
(async () => {
const degiro: DeGiro = new DeGiro({
username: 'your_username_here',
pwd: '***********',
})
await degiro.login()
const result = await degiro.searchProduct({ text: 'AAPL' })
console.log(JSON.stringify(result, null, 2))
})()
Search TSLA stock
import DeGiro, { DeGiroEnums, DeGiroTypes } from 'degiro-api'
const { DeGiroProducTypes } = DeGiroEnums
(async () => {
const degiro: DeGiro = new DeGiro({
username: 'your_username_here',
pwd: '***********',
})
await degiro.login()
const result = await degiro.searchProduct({
text: 'TSLA',
type: DeGiroProducTypes.shares,
limit: 1,
})
console.log(JSON.stringify(result, null, 2))
})()
getCashFunds(): Promise<CashFoundType[]>
getPortfolio(config: GetPorfolioConfigType): Promise<any[]>
getPortfolio
config parameter could have:
type: set the types or positions you want to fetch. Could be:
getProductDetails: if is set to true the positions results will have a productData
field with all the product details.
Get all open positions:
import DeGiro, { DeGiroEnums, DeGiroTypes } from 'degiro-api'
const { PORTFOLIO_POSITIONS_TYPE_ENUM } = DeGiroEnums
(async () => {
const degiro: DeGiro = new DeGiro({
username: 'your_username_here',
pwd: '**********',
})
await degiro.login()
const portfolio = await degiro.getPortfolio({
type: PORTFOLIO_POSITIONS_TYPE_ENUM.ALL,
getProductDetails: true,
})
console.log(JSON.stringify(portfolio, null, 2))
})()
Also you can fetch your portfolio data this way:
import DeGiro, { DeGiroEnums, DeGiroTypes } from 'degiro-api'
const { PORTFOLIO_POSITIONS_TYPE_ENUM } = DeGiroEnums
(async () => {
const degiro: DeGiro = new DeGiro({
username: 'your_username_here',
pwd: '**********',
})
await degiro.login()
const portfolio = await degiro.getPortfolio({ type: PORTFOLIO_POSITIONS_TYPE_ENUM.ALL })
console.log(JSON.stringify(portfolio, null, 2))
})()
And getting product details too
import DeGiro, { DeGiroEnums, DeGiroTypes } from 'degiro-api'
const { PORTFOLIO_POSITIONS_TYPE_ENUM } = DeGiroEnums
(async () => {
const degiro: DeGiro = new DeGiro({
username: 'your_username_here',
pwd: '**********',
})
await degiro.login()
const portfolio = await degiro.getPortfolio({
type: PORTFOLIO_POSITIONS_TYPE_ENUM.ALL,
getProductDetails: true,
})
console.log(JSON.stringify(portfolio, null, 2))
})()
#### getFavouriteProducts()
getFavouriteProducts(): Promise<FavouriteProductType[]>
#### getPopularStocks()
getPopularStocks(): Promise<StockType[]>
getOrders(options: GetOrdersConfigType): Promise<GetOrdersResultType>
getHistoricalOrders(options: GetHistoricalOrdersOptionsType): Promise<HistoricalOrdersType>
createOrder(order: OrderType): Promise<CreateOrderResultType>
OrderType
DeGiroActions
DeGiroMarketOrderTypes
DeGiroTimeTypes
CreateOrderResultType
TransactionFeeType
import DeGiro, { DeGiroEnums, DeGiroTypes } from 'degiro-api'
const { DeGiroActions, DeGiroMarketOrderTypes, DeGiroTimeTypes } = DeGiroEnums
const { OrderType } = DeGiroTypes
(async () => {
const degiro: DeGiro = new DeGiro({
username: 'your_username_here',
pwd: '************'
})
await degiro.login()
const order: OrderType = {
buySell: DeGiroActions.BUY,
orderType: DeGiroMarketOrderTypes.LIMITED,
productId: '331868', // $AAPL - Apple Inc
size: 1,
timeType: DeGiroTimeTypes.DAY,
price: 272, // limit price [Degiro could reject this value]
// stopPrice: 2,
}
const { confirmationId, freeSpaceNew, transactionFees } = await degiro.createOrder(order)
console.log(JSON.stringify({ confirmationId, freeSpaceNew, transactionFees }, null, 2))
})()
executeOrder(order: OrderType, executeId: string): Promise<String>
import DeGiro, { DeGiroEnums, DeGiroTypes } from 'degiro-api'
const { DeGiroActions, DeGiroMarketOrderTypes, DeGiroTimeTypes } = DeGiroEnums
const { OrderType } = DeGiroTypes
(async () => {
try {
const degiro: DeGiro = new DeGiro({
username: 'nachoogoomezomg',
pwd: <string>process.env.DEGIRO_PWD,
})
await degiro.login()
const order: OrderType = {
buySell: DeGiroActions.BUY,
orderType: DeGiroMarketOrderTypes.LIMITED,
productId: '331868', // $AAPL - Apple Inc
size: 1,
timeType: DeGiroTimeTypes.DAY,
price: 270, // limit price
// stopPrice: 2,
}
const { confirmationId, freeSpaceNew, transactionFees } = await degiro.createOrder(order)
const orderId = await degiro.executeOrder(order, confirmationId)
console.log(`Order executed with id: ${orderId}`)
} catch (error) {
console.error(error)
}
})()
deleteOrder(orderId: String): Promise<void>
import DeGiro, { DeGiroEnums, DeGiroTypes } from 'degiro-api'
const { DeGiroActions, DeGiroMarketOrderTypes, DeGiroTimeTypes } = DeGiroEnums
const { OrderType } = DeGiroTypes
(async () => {
const degiro: DeGiro = new DeGiro({
username: 'nachoogoomezomg',
pwd: <string>process.env.DEGIRO_PWD,
})
await degiro.login()
const order: OrderType = {
buySell: DeGiroActions.BUY,
orderType: DeGiroMarketOrderTypes.LIMITED,
productId: '331868', // $AAPL - Apple Inc
size: 1,
timeType: DeGiroTimeTypes.DAY,
price: 272, // limit price
// stopPrice: 2,
}
const { confirmationId, freeSpaceNew, transactionFees } = await degiro.createOrder(order)
const orderId = await degiro.executeOrder(order, confirmationId)
console.log(`Order executed with id: ${orderId}`)
// Wait few seconds to avoid "Rate limit for the given request exceeded" error
const TIMEOUT_SECONDS = 2 * 1000
const deleteOrderFunction = async () => {
try {
await degiro.deleteOrder(orderId)
console.log('Order removed')
} catch (error) {
console.error(error)
}
}
setTimeout(deleteOrderFunction, TIMEOUT_SECONDS)
})()
#### getProductsByIds()
getProductsByIds(ids: string[]): Promise<any[]>
#### getNews()
getNews(options: GetNewsOptionsType): Promise<NewsType>
#### getWebi18nMessages()
getWebi18nMessages(lang: string): Promise<i18nMessagesType>
#### getWebSettings()
getWebSettings(): Promise<WebSettingsType>
#### getWebUserSettings()
getWebUserSettings(): Promise<WebUserSettingType>
#### getConfigDictionary()
getConfigDictionary(): Promise<ConfigDictionaryType>
If you code with typescript and use IntelliSense you are going to get access to all objects properties and all stuff...
If you not, in the docs section could find all methods, functions, types, whatever you want. Don't waste more time and click here to see the documentation.
We need help with the next endpoint:...
degiro-cli is an usefull command line interface that help us dealing with DeGiro platform through the terminal. You can see your portfolio status, create and execute orders and much more (may in the future)
$ degiro
Usage: DeGiro Command Line Interface [options] [command]
DeGiro CLI provide you access to DeGiro Broker across the terminal
Options:
-V, --version output the version number
-h, --help display help for command
Commands:
login validate credentials with DeGiro platform
search Search products in DeGiro
portfolio show account portfolio in real-time
help [command] display help for command
MIT
FAQs
Unofficial DeGiro API for Javascript. Buy and sell in the stock market. See your portfolio and much more
The npm package degiro-api receives a total of 16 weekly downloads. As such, degiro-api popularity was classified as not popular.
We found that degiro-api demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.