Giter Site home page Giter Site logo

wikifolio's Introduction

📊 Wikifolio API

This is an unofficial Node.js API client for Wikifolio's platform.

⚠️ Wikifolio could change their API at any moment. ⚠️
If anything is broken, please open an issue.

⚠️ On the 7th of april 2021, Wikifolio announced a re-launch of their website, which is likely to (temporarily) break this API. ⚠️

divider

⭐ Features

  • Session management
  • Search wikifolios
  • Fetch wikifolio details / analysis / price
  • Fetch portfolio positions
  • Fetch wikifolio trades
  • Fetch watchlist entries
  • Watch / unwatch wikifolios
  • Fetch users & their wikifolios
  • Trading: place & modify buy & sell orders

divider

🌞 Contributors wanted

divider

🛫 Install

# using npm
npm i wikifolio

# using yarn
yarn add wikifolio

divider

📝 Examples

The examples assume the following setup:

import Api from 'wikifolio'

const api = new Api({
  email: '[email protected]',
  password: 'plaintext-password'
})

☝️ Use encrypted environment variables or command line prompts, never store your passwords in plain text.

divider

1. Fetch details of a wikifolio

const wikifolio = api.wikifolio('wfobserver')
console.log( await wikifolio.details() )

divider

2. Fetch wikifolio price

const wikifolio = api.wikifolio('wfobserver')
console.log( await wikifolio.price() )

divider

3. Fetch wikifolio trades

const wikifolio = api.wikifolio('wfobserver')
console.log( await wikifolio.trades({pageSize: 100, page: 1}) )

divider

4. Fetch wikifolio index history (chart)

const wikifolio = api.wikifolio('wfobserver')
console.log( await wikifolio.history() )

divider

5. Fetch portfolio items of a wikifolio

const wikifolio = api.wikifolio('wfobserver')
console.log( await wikifolio.portfolio() )

divider

6. Search wikifolios

const wikifolios = await api.search({query: 'Supervisor'})
console.log( wikifolios )

divider

7. Unwatch all wikifolios on the watchlist

const watchlist = await api.watchlist()
for(const wikifolio of watchlist){
    await wikifolio.watchlist(false)
}

divider

8. Get trader info

const user = api.user('riennevaplus')
console.log( await user.details() )

divider

9. Get wikifolios of a trader

const user = api.user('riennevaplus')
console.log( await user.wikifolios() )

divider

10. Place a limit order

There's a similar sell() method.

const wikifolio = api.wikifolio('wfobserver')
const order = await wikifolio.buy({
    amount: 1,
    limitPrice: 220,
    orderType: "limit",
    underlyingIsin: "DE000LS9NMQ9",
    expiresAt: "2020-07-29T00:00:00.000Z"
})

Note: When orderType is set to quote the first returned quote will be accepted.

divider

11. Update an order

const wikifolio = api.wikifolio('wfobserver')
const order = wikifolio.order('8b4da005-6750-4b4c-9dff-0364d3e07be0')
console.log( await order.submit({limitPrice: 100}) )

divider

12. List & remove wikifolio orders

const wikifolio = api.wikifolio('wfobserver')
const orders = await wikifolio.orders({pageSize: 25, page: 0})

for(const order of orders){
    console.log( await order.remove() )
}

divider

👷 Todos

  • Improve documentation
  • Implement wikifolio sustainability

divider

🌻 Contributors

wikifolio's People

Contributors

dependabot[bot] avatar jekru avatar riennevaplus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

wikifolio's Issues

⚠️ It will (probably) break soon.

A few days ago, wikifolio announced a relaunch, which is highly likely to break this API - please be warned.

I will try to fix things, but there will be a delay, as this is a side project of my free time.
Pull requests are always welcome.

Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.

I have some issues to get this running. I'm new to nodejs, so maybe I'm doing something wrong here. That's what I do on Ubuntu:

sudo npm install --global yarn
mkdir build; cd build
cat <<EOF >>wiki.ts
import Api from 'wikifolio'
const api = new Api({email: '[email protected]', password: 'examplepassword1337'})
EOF
sudo yarn init
sudo yarn add wikifolio
node wiki.ts
(node:4566) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
/home/m/Desktop/build/wiki.ts:1
import Api from 'wikifolio'
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at wrapSafe (internal/modules/cjs/loader.js:915:16)
    at Module._compile (internal/modules/cjs/loader.js:963:27)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
    at Module.load (internal/modules/cjs/loader.js:863:32)
    at Function.Module._load (internal/modules/cjs/loader.js:708:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12)
    at internal/main/run_main_module.js:17:47

Some sort of import error, but I don't know what I'm missing.

Feature Request: Download 'Kontoauszug' from 'Analyse'-Tab

From the Wikifolio-Website it is possible to download two sorts of CSV files for a given portfolio. The feature is available in the Tab "Analyse". A user can enter a start date and a end date and then klick a button to download the price (on a daily basis) and the account statement (Kontoauszug). I understand that obtaining the price of the portfolio on a daily basis is already covered in this API, however downloading the account statement is not to the best of my knowledge. The account statement lists with great details all trades including the exact quantity, time of day, execution price and fee for a given stock order and also the amount of cash in the portfolio before and after the trade. I do believe this is a very useful feature which can benefit the API and its users.

image

Below is an example of the data in the CSV file.

Datum (UTC) | Beschreibung | ISIN | Änderung Anzahl | Anzahl nachher | Preis | Preis (Brutto) | Änderung Cash | Cash nachher
13.12.2020 23:59 | Zertifikategebühr |   |   |   |   | -109,804 | 685536,405
14.12.2020 08:06 | Wertpapier-Transaktion (Kauf) | DE0006305006 | 20.000,00 | 20.000,00 | 5,030 |   | -100600,000 | 584936,405
14.12.2020 08:20 | Wertpapier-Transaktion (Kauf) | DE0007568578 | 5.000,00 | 15.000,00 | 15,320 |   | -76600,000 | 508336,405
14.12.2020 23:59 | Zertifikategebühr |   |   |   |   | -109,966 | 508226,439
15.12.2020 16:26 | Wertpapier-Transaktion (Kauf) | DE0007568578 | 5.000,00 | 20.000,00 | 15,500 |   | -77500,000 | 430726,439

Your opinion on this topic is very much appreciated, good Sir.

Does you API work?

Does you implementation of the API currently work? At the moment its impossible for me to even place a limit order which has worked flawlessly in the past time. But today I got

{
 "success":false,
 "reason":"An error of unclarified origin has occurred. If the error persists, contact [email protected]."
}

Order cannot be placed

Hi,

I'm facing the following issue while executing an order:

Your credentials will not be stored.
2021-09-17T00:00:00.000Z
(node:2593) UnhandledPromiseRejectionWarning: Error: Unable to submit order (Bei Limit- oder Stoplimitorders muss das Gültigkeitsdatum angegeben werden.)
    at Order.<anonymous> (/home/julian/experiments/nodejs/projects/wikifolio/wikifolio-example/node_modules/wikifolio/dist/models/Order.js:151:35)
    at step (/home/julian/experiments/nodejs/projects/wikifolio/wikifolio-example/node_modules/wikifolio/dist/models/Order.js:44:23)
    at Object.next (/home/julian/experiments/nodejs/projects/wikifolio/wikifolio-example/node_modules/wikifolio/dist/models/Order.js:25:53)
    at fulfilled (/home/julian/experiments/nodejs/projects/wikifolio/wikifolio-example/node_modules/wikifolio/dist/models/Order.js:16:58)
    at process._tickCallback (internal/process/next_tick.js:68:7)
(node:2593) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:2593) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

I did pass the same timestamp as the api does, when placing an order in the browser.

Error: Login failed, Cookie not found

Error: Login failed, Cookie not found
at Api. (.....\node_modules\wikifolio\src\models\Api.ts:86:8)

Now res.body returns "/de/de/l/wikifolios-finden" and when i replaced the "/dashboard" and "/uebersicht" with "/wikifolios-finden" then it works.

image

Bug: res.body has changed for some accounts

(node:13852) UnhandledPromiseRejectionWarning: Error: Login failed, Cookie not found
    at Api.<anonymous> (C:\Users\user\Desktop\wikifolio\src\models\Api.ts:80:10)
    at step (C:\Users\user\Desktop\wikifolio\src\models\Api.ts:44:23)
    at Object.next (C:\Users\user\Desktop\wikifolio\src\models\Api.ts:25:53)
    at fulfilled (C:\Users\user\Desktop\wikifolio\src\models\Api.ts:16:58)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)

POST https://www.wikifolio.com/dynamic/de/de/login/login

Result: /de/de/alle-wikifolios/uebersicht
Expected result: /de/de/dashboard

With an "old" account (> 1 year), res.body is still /de/de/dashboard. The /uebersicht result came with a fairly new account (4-6 weeks). I don't know if the age of an account is the reason for the different behavior but this was the only parameter I could identify that differed.

Api.ts

if(!res.body.endsWith('/dashboard') || !res.request.headers['cookie'])
   throw new Error('Login failed, Cookie not found')

new to javascript, can't get anything to work

Hi, I'm totally new to javascript and I can't get this to run. I made a new folder and run inside this

npm init
npm i wikifolio

I created a new file index.js with this content

import Api from 'wikifolio'

const api = new Api({
  email: 'my email',
  password: 'my password'
})

const wikifolio = api.wikifolio('wf000igb03')
console.log( await wikifolio.details() )
console.log( await wikifolio.price() )

But I get the following error when running node index:

(node:6987) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
/Users/henryhaustein/Downloads/wikifolio/index.js:1
import Api from 'wikifolio'
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at Object.compileFunction (node:vm:352:18)
    at wrapSafe (node:internal/modules/cjs/loader:1032:15)
    at Module._compile (node:internal/modules/cjs/loader:1067:27)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1157:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12)
    at node:internal/main/run_main_module:17:47

When I add "type": "module" to the package.json file I get the following error

file:///Users/henryhaustein/Downloads/wikifolio/index.js:3
const api = new Api({
            ^

TypeError: Api is not a constructor
    at file:///Users/henryhaustein/Downloads/wikifolio/index.js:3:13
    at ModuleJob.run (node:internal/modules/esm/module_job:197:25)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:337:24)
    at async loadESM (node:internal/process/esm_loader:88:5)
    at async handleMainPromise (node:internal/modules/run_main:61:12)

Buy with orderType Quote causes Missing UnderlyingQuote Error

I'm using this solution to develop a nodeJS terminal app to simulate stock operations.

Everything all right when buying with limit as orderType but something goes wrong when using quote instead. Am I missing some parameter?

Expected Behavior

When calling the buy method with quote as typeOrder the operation should work just like 'limit' orders.

Current Behavior

The following error appears:

# Unknown Error: Unable to submit order (Bei Requoteorders muss das UnderlyingQuote angegeben werden.)

Steps to Reproduce

  1. NodeJS, Yarn and Typescript

  2. Code to buy stocks (simplified to make it easier to find the possible cause)

wikifolio.services.ts

import Api, { OrderParam } from 'wikifolio';

const API_KEY = 'HIDDEN DUE SECURITY REASONS';
const SAMPLE_ISIN = 'DE000LS9NMQ9';

const getExpirationDate = (): Date => {
  const now = new Date();
  now.setMinutes(now.getMinutes() + 30);
  return new Date(now);
};

export const buyWikifolio = async (
  email: string,
  password: string,
  order: Partial<OrderParam>
) => {
  const api = new Api({ email, password });
  const wikifolio = api.wikifolio(API_KEY);

  // with **_quote_** the error (Bei Requoteorders muss das UnderlyingQuote angegeben werden) occurs
  const orderType:any = 'limit';
  
  order = {
    ...order,
    orderType,
    expiresAt: getExpirationDate()
  };

  console.log('this is my order', order);

  return await wikifolio.buy(order);
};

index.ts

import { buyWikifolio } from './services/wikifolio.services';
import { Order, OrderParam } from 'wikifolio';

const order: Partial<OrderParam> = {
  amount: 2,
  limitPrice: 100,
  underlyingIsin: 'DE000LS9NMQ9',
};

buyWikifolio(email, password, order)
  .then((result: Order) => {
    console.log(result);
  })
  .catch((error) => console.log(error))
  .finally(() => process.exit());

package.json

  "dependencies": {
    "request": "^2.88.2",
    "wikifolio": "^0.3.3"
  },
  "devDependencies": {
    "typescript": "^4.4.3"
  }

tsconfig.json

{
  "compilerOptions": {
    "esModuleInterop": true,
    "module": "CommonJS",
    "noImplicitAny": true,
    "outDir": "build",
    "preserveConstEnums": true,
    "removeComments": true,
    "sourceMap": false
  },
  "include": ["src/**/*", "services", "index.ts"],
  "exclude": ["node_modules", "**/*.spec.ts"]
}

Context (Environment)

Trying to execute a quote operation. In the following screenshot I have two examples of the response the API call is giving me.

In the first attempt I tried to send all the possible values and in the second one only the limitPrice, amount, underlyingIsin, orderType and expiresAt.

image

Thanks in advance

Error: Cannot find module 'request'

Hi RienNeVaPlus,

thank you for publishing this great project! you're the only one on the net that I found that provides a wikifolio api solution.
I tried to rebuild it in C# from your code-base but got stuck with my http post requests, that did not result in the same response of the authCookie as your code does or as the wikifolio page itself does when you login.

So I tried to run your code, unfortunately I'm a total noob in typescript.

Working with Visual Studio Code, I created a very small sample script:

import Api from 'wikifolio'

const email = "myemail";
const password = "mypassword";

const api = new Api({email, password});

const wikifolio = api.wikifolio('wfobserver')

const details = async () => {
    await wikifolio.details()
}
console.log( details )

and then ran tsc test.ts which worked fine, followed by node test.js
which throws the following error:

PS C:\Users\Gordon\nodeWikifolio\execution> node test.js
internal/modules/cjs/loader.js:905
  throw err;
  ^

Error: Cannot find module 'request'
Require stack:
- C:\Users\Gordon\nodeWikifolio\node_modules\request-promise-native\lib\rp.js
- C:\Users\Gordon\nodeWikifolio\node_modules\wikifolio\dist\utils.js
- C:\Users\Gordon\nodeWikifolio\node_modules\wikifolio\dist\models\Api.js
- C:\Users\Gordon\nodeWikifolio\node_modules\wikifolio\dist\models\index.js
- C:\Users\Gordon\nodeWikifolio\node_modules\wikifolio\dist\index.js
- C:\Users\Gordon\nodeWikifolio\execution\test.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:902:15)
    at Function.Module._load (internal/modules/cjs/loader.js:746:27)
    at Module.require (internal/modules/cjs/loader.js:974:19)
    at require (internal/modules/cjs/helpers.js:92:18)
    at C:\Users\Gordon\nodeWikifolio\node_modules\request-promise-native\lib\rp.js:8:12
    at module.exports (C:\Users\Gordon\nodeWikifolio\node_modules\stealthy-require\lib\index.js:62:23)
    at Object.<anonymous> (C:\Users\Gordon\nodeWikifolio\node_modules\request-promise-native\lib\rp.js:7:15)
    at Module._compile (internal/modules/cjs/loader.js:1085:14)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
    at Module.load (internal/modules/cjs/loader.js:950:32) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    'C:\\Users\\Gordon\\nodeWikifolio\\node_modules\\request-promise-native\\lib\\rp.js',
    'C:\\Users\\Gordon\\nodeWikifolio\\node_modules\\wikifolio\\dist\\utils.js',
    'C:\\Users\\Gordon\\nodeWikifolio\\node_modules\\wikifolio\\dist\\models\\Api.js',
    'C:\\Users\\Gordon\\nodeWikifolio\\node_modules\\wikifolio\\dist\\models\\index.js',
    'C:\\Users\\Gordon\\nodeWikifolio\\node_modules\\wikifolio\\dist\\index.js',
    'C:\\Users\\Gordon\\nodeWikifolio\\execution\\test.js'
  ]
}

Can you see where I am doing something wrong? I am trying to solve/google the problem for multiple hours now without success.

Thanks for the great work and greetings!

general questions, totally new to typescript and trying to get this to run

Hello there,

thank you very much for sharing your code! I gave it a try but couldn't get it to run thus far
--- which certainly is because of my complete lack of experience with javascript/typescript.

Would it be possible to provide a little shell script (or example typescript files) for starting from scratch
(I'm on Ubuntu 18 LTS), and helping complete novices like me to get typescript, and consequently this repo, to run?
This repo has some pretty code snippets in the readme already, but I seem to fail putting the puzzle pieces together.

Alternatively, I would very much appreciate some help on what I tried so far:

  1. installing typescript and wikifolio globally
sudo npm install -g typescript
sudo npm install -g wikifolio
  1. creating a toy script wikifolio.ts, containing the lines:
import {Wikifolio} from "/usr/local/lib/node_modules/wikifolio";

var email = "[email protected]";
var password = "verySecretPassword";
const wiki = new Wikifolio({email, password});

const wikifolio = wiki.wikifolio('wfobserver');
console.log(await wikifolio.trades({pageSize: 100, page: 1}));

Note that I changed the line

import {Wikifolio} from "wikifolio";

because this was throwing an error

wikifolio.ts:1:25 - error TS2307: Cannot find module 'wikifolio' or its corresponding type declarations.

that is now apparently resolved by using the absolute path to the module.

  1. then tried to compile the file via

tsc wikifolio.ts

.. but this throws a compile-time error

wikifolio.ts:8:13 - error TS1378: Top-level 'await' expressions are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher.
8 console.log(await wikifolio.trades({pageSize: 100, page: 1}));

This is essentially where I got entirely lost, been trying to go for

'tsc wikifolio.ts --module esnext --target es2017'

.. but then it's back at not finding the module anymore:

wikifolio.ts:1:25 - error TS2307: Cannot find module '/usr/local/lib/node_modules/wikifolio' or its corresponding type declarations.
1 import {Wikifolio} from "/usr/local/lib/node_modules/wikifolio";

  1. This is seemingly just the compiling. Is it possible to run the compiled script as a process in the terminal?

These lines likely give you an idea of my complete lack of knowledge of typescript. Any help would be much appreciated. Cheers!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.