# Trading API

Version: 0.2.1-SNAPSHOT

## Get started

### Overview

Trading API (TAPI) is a part of the standard Consorsbank trading application ActiveTrader / ActiveTrader Pro. It allowes to write user managed application for the specific trading activities. TAPI support pull / push requests and based on the Google Remote Procedure Call (GRPC) technology.

With help of the TAPI you have an access to the accounts, orders, depots and market data information.

| Important This documentation is the description of the early version of Trading API. It’s not final and it’s subject to change. With the lookback to the new BaFin regulation it’s especially important to understand that the ordering part of the TAPI can be partially changed to fullfil new law directives.

Additional information and discussions can be found there. Please contact to the support team to get access to this part of the community.

### Requirements

- Active Trader / Active Trader Pro with Java 8 64 bits, minimum 8Gb RAM

- Client Java 8 or higher 64 bits

### License

Trading-API is licensed under Apache 2.0 license.

The license and notice texts can be found in the delivered LICENSE and NOTICE.TXT files.

### Communication

GRPC technology uses one connection to transfer all necessary data beetwen client and ActiveTrader. As developer you don’t need to care about communication. All low level communication, security and converting functions takes TAPI engine. You can concentrate on the high level functions and bussines logic of the application.

### Security

TAPI uses HTTP/2 protocol with RSA protection. RSA self signed certificate can be generated directly in the ActiveTrader application. Typical use case is to use user application from same PC, but it’s also possible to connect from the remote machine.

| Important To accept self signed certificate from the user application is necessary to use trusted part of the RSA keys (Trust Certificate) by the connection initialization in the client application. This certificate can be exported from the ActiveTrading application.

To provide users access control can be used secret string. That’s an equivalent of password. Secret is defined in the Active Trader and used only for validation. User application sends secret to the ActiveTrader. If the validation in the ActiveTrader is passed then ActiveTrader generates a session access token and returns it to the user application. With this token is possible to execute other requests. After end of processing the token should be invalidated.

| Important We don’t keep secret data in the configuration. Only double MD5 hash of the secret + solt is stored in the configuration. As result we can’t restore the secret. For more information see Defense against rainbow tables

### Configuration

To activate TAPI is need to complete next steps:

1 | Select Trading-API settings in the configuration
2 | Activate TAPI checkbox
3 | Optional: if key exists, press [GENERATE NEW KEY] button

In the opened dialog

1 | Enter or correct key settings
2 | Press [GENERATE NEW KEY] button and wait unil new key is generated
3 | Press [OK] button to accept new settings

After confirmation of the new settings TAPI will be activated.

| Warning In some cases if any initialization errors are appear, the TAPI activation indication in the status bar of the application will be red. To check activation problems move mouse cursor over this indication and check tooltip for the error.

Before to start using client application, it’s need to export trusted certificate from ActiveTrader.

1 | Set secret for an access control. Longer string is better.
2 | Press [EXPORT TRUST CERTIFICATE] and store file (for example with name: roots.pem) to the location where client application can use it.

### Session TAN

Some operations of the TAPI can be used without TAN. All activities with the necessity of the autorisation are need to use of the session TAN.

| Important Do not forget to activate session TAN. It’s not possible to use individual TAN’s with TAPI

## Usage of the Trading API

### Source code

An example aplication is delivered with precompiled GRPC libraries. If you want to generate source code by youself you can use protobuf files from protobuf directory. Please refer to the Java Generated Code Reference.

### Initialization

To initialize client application and connect to the ActiveTrader with help of TAPI you have to process next steps:

| Important All examples are avialable as a sorce code and can be found in the specific folders. Input point is the file TestClient.java To start examples you have to put into start parameters full path to the trust certificate and secret. For example: "C:\PathToTrustCert\roots.pem 1234567"

Initialize the root GRPC engine with trusted certificate, exported from configuration dialog of the ActiveTrader.

Example Java: Initaialize GRPC

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41

      private String accessToken = "";

    /**
     * Test client.
     */
    public static void main(String[] args) throws Exception {
      if (args.length<2) {
        System.err.println("Please generate key in AT and "
            + "put location of the trust certificate and secret as arguments");
        System.exit(-1);
      }
      File caFile = new File(args[0]); (1)

      if (!caFile.isFile()) { (2)
        System.err.println("File: "+caFile+" does not exist");
        System.exit(-1);
      }

      String server = "localhost"; (3)
      int port = 40443;

      System.err.println("Connecting... "+server+":"+port);
      try (TestClient client = new TestClient(server, port, caFile, args[1])) { (4)

        // ...

      } catch (Exception e) {
        e.printStackTrace();
      }
    }

    public TestClient(String host, int port, File caFile, String secret) throws SSLException {
      this(NettyChannelBuilder.forAddress(host, port)
          .negotiationType(NegotiationType.TLS)
          .sslContext(GrpcSslContexts.forClient().trustManager(caFile).build())
          .build());
      accessToken = login(secret);
      if (accessToken.isEmpty()) {
        // Error
      }
    }

1 | Get trusted certificate location as a parameter of the command line
2 | Check if a file of the cetrificates exists
3 | Define connection settings
4 | Initialize GRPC connection

### Services and functions definition

After an initialization is GRPC ready and it can be used for the building service stubs to operate with TAPI services. Stubs are sets of service functions with help of then is possible to access data and execute user actions. They are very similar to the normal programming functions with small differences.

- Each remote function can have one (and only one) input parameter.

- Each remote function can have one (and only one) result parameter.

- The function can send data asynchronically

Functions can be simple (one request → one reply), server sends events (one request from client → many replies from server), client sends events (many requests from client → one reply from server) or server and clients sends events (many requests from client → many replies from server). TAPI uses only first and second types of functions. First type of the function used for the simple user activity (pull) and second type for subcriptions or streaming (push).

Services and functions are defined in the special files as protobuf protocol v.3

Example Protobuf: RPC definition

      1
    2
    3
    4

      service ServiceName { (1)
      rpc SimpleFunction(ClientParameterType1) returns (ServerParameterType1); (2)
      rpc PushFunction(ClientParameterType2) returns (stream ServerParameterType2); (3)
     }

1 | ServiceName is service stub name. This name will used for the access to the service functions
2 | SimpleFunction is simple request / reply function.
3 | PushFunction is push function with one request and streams data from the server. Please check stream keyword before ServerParameterType2

| Important You don’t need to use protobuf files directly, but it’s good idea to know a syntax of the the protocol. These files are need if you want to use TAPI with other progaming languages. grpc.io conatains all necessary infomation about code generation and usage for all supported programming languages.

### Create services

There are two types of the service functions: blocking and unblocking service functions. Blocking service functions are used for the synchronical answer from the function and similar to the typical program functions. By call of the blocking functions, program waits until a result of the function is arrived. It can produce timeouts by the execution. Unblocking function are used for the background processing. In this case a program don’t wait until result is arrived and listen for the result asynchronically. This type of the stubs is used for the push functions. For more information please refer to the grpc.io web site.

For blocking calls used blocking service stubs, for asynchronical calls unblocking service stubs.

Example Java: Initaialize Stubs

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25

      private final ManagedChannel channel;
    private final AccessServiceGrpc.AccessServiceBlockingStub accessServiceBlockingStub;
    private final SecurityServiceGrpc.SecurityServiceBlockingStub securityServiceBlockingStub;
    private final SecurityServiceGrpc.SecurityServiceStub securityServiceStub;
    private final StockExchangeServiceGrpc.StockExchangeServiceBlockingStub stockExchangeServiceBlockingStub;
    private final AccountServiceGrpc.AccountServiceBlockingStub accountServiceBlockingStub;
    private final AccountServiceGrpc.AccountServiceStub accountServiceStub;
    private final OrderServiceGrpc.OrderServiceStub orderServiceStub;
    private final OrderServiceGrpc.OrderServiceBlockingStub orderServiceBlockingStub;
    private final DepotServiceGrpc.DepotServiceStub depotServiceStub;
    /**
     * Construct client for accessing ActiveTrader using the existing channel.
     */
    TestClient(ManagedChannel channel) { (1)
      this.channel = channel;
      securityServiceBlockingStub = SecurityServiceGrpc.newBlockingStub(channel); (2)
      securityServiceStub = SecurityServiceGrpc.newStub(channel); (3)
      stockExchangeServiceBlockingStub = StockExchangeServiceGrpc.newBlockingStub(channel);
      accountServiceBlockingStub = AccountServiceGrpc.newBlockingStub(channel);
      accountServiceStub = AccountServiceGrpc.newStub(channel);
      orderServiceStub = OrderServiceGrpc.newStub(channel);
      orderServiceBlockingStub = OrderServiceGrpc.newBlockingStub(channel);
      depotServiceStub = DepotServiceGrpc.newStub(channel);
      accessServiceBlockingStub = AccessServiceGrpc.newBlockingStub(channel);
    }

1 | Use managed channel from previous step
2 | Initialize blocking stub
3 | Initialize non blocking stub

| Warning Be care that you use non blocking stub to subscribe for push events. It’s technically possible, but blocks program execution until server will stop send events.

### Functional programming

Objects in the GRPC world are immutable (or not changable). To create these objects are used object builders. They fill objects and build final immutable object for the execution. It looks like a chain of the functions calls.

Example Java: Create object

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

      AddOrderRequest request = AddOrderRequest.newBuilder() (1)
        .setAccessToken(accessToken) (2)
        .setAccountNumber("123467890")
        .setSecurityWithStockexchange(securityWithStockExchange)
        .setValidation(Validation.VALIDATE_ONLY)
        .setAmount(1)
        .setOrderModel(OrderModel.LIMIT)
        .setLimit(1)
        .setOrderType(OrderType.BUY)
        .setCashQuotation(CashQuotation.KASSA)
        .setValidityDate(Date.newBuilder().setDay(10).setMonth(10).setYear(2018).build())
        .build(); (3)

1 | Create builder
2 | Set objects parameters
3 | Build final object

| Important It’s necessary to fill only parameters that need for the function call. All other parameters should stay untouched or should have default values.

### Pull and push functions

There is two possibilites to call remote function.

#### Pull requests

The first one is using blocking service stub. In this case an operation blocks program execution until results are arrived.

Example Java: Blocking execution

      1
    2
    3
    4
    5
    6

      private TradingAccounts getTradingAccounts() {
      AccessTokenRequest request = AccessTokenRequest.newBuilder()
          .setAccessToken(accessToken)
          .build();
      return accountServiceBlockingStub.getTradingAccounts(request);
    }

#### Push requests

Other possibility is not to wait for the results, but listen for then asynchronically.

Example Java: Noblocking execution

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

      private void getTradingAccountsAsync() {
      AccessTokenRequest request = AccessTokenRequest.newBuilder()
          .setAccessToken(accessToken)
          .build();
      accountServiceStub.getTradingAccounts(request, new StreamObserver<TradingAccounts>() { (1)
        @Override
        public void onNext(TradingAccounts tradingAccounts) {
          System.out.println(tradingAccounts); (2)
        }

        @Override
        public void onError(Throwable t) {
          t.printStackTrace(); (3)
        }

        @Override
        public void onCompleted() {
          System.out.println("No results anymore"); (4)
        }
      });
    }

1 | Subscribe for the results
2 | Process results
3 | Called by technical error
4 | Called after processing end. No new result are comming anymore.

The results are comming only once. The operation will be automatically completed.

#### Push subscriptions

In some cases server can sent more then one answer or streams the data. This case is simular t requests, but has some differences.

- It can come more then one results answer back

- Server can send "break" notification to the client if no data is exist anymore

- Client can send "break" notification to the server if no data is need anymore. See ServerSubs

## Services and functions

### Access service

Access service provides functionality to validation / invalidation of the client.

Table 1. AccessService
Function | Description
--- | ---
LoginReply = Login(LoginRequest) | Validates client by the TAPI and gets access data
LogoutReply = Logout(LogoutRequest) | Invalidates client by the TAPI and gets logout result

#### Client validation

Client validation should be a first request after connection initalization. To validate client you have to set a secret that was set in the ActiveTrader configuration and process a login function. As result of this function returned session access token. This token is necessary to set to each request that will be send by TAPI.

Example Java: Login

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

      private String login(String secret) {
      LoginRequest loginRequest = LoginRequest.newBuilder()
          .setSecret(secret)
          .build();
      LoginReply loginReply = accessServiceBlockingStub.login(loginRequest);
      if (loginReply.getError()!=Error.getDefaultInstance()) {
        System.err.println(loginReply.getError());
        return "";
      } else {
        return loginReply.getAccessToken();
      }
    }

#### Client invalidation

After finishing of usage of the TAPI is necessary to invalidate session. That can be done with help of the logout function. .Example Java: Logout

    private void logout() {
      if (accessToken!=null && !accessToken.isEmpty()) {
        LogoutRequest request = LogoutRequest.newBuilder()
            .setAccessToken(accessToken)
            .build();
        accessServiceBlockingStub.logout(request);
      }
    }

### Account service

Account service provides access to the trading accounts and gives possibility to access to the accounts data and transactions.

Table 2. AccountService
Function | Description
--- | ---
TradingAccounts = GetTradingAccounts(AccessTokenRequest) | Gets trading accounts @return TradingAccounts List of trading accounts
TradingAccountInformation ⇐ StreamTradingAccount(TradingAccountRequest) | Subscribes one trading account for updates @param TradingAccount Trading account for push @stream TradingAccountInformation Specific information for subscribed account (balance, kredit line, etc.)
TradingAccountTransactions ⇐ StreamTradingAccountTransactions(TradingAccountRequest) | Subscribes one trading account for the transactions updates @param TradingAccount Trading account for push @stream TradingAccountInformation Transactions list for subscribed account

To subscribe for the account and transactions changes you have to get trading accounts and subscribe each account with help of steam functions for data changes independently.

#### Get list of trading accounts

Many activites need information about an account data. Most important information is a trading account number. To get list of all avialable trading accounts you have to use Get Trading Accounts function.

Example Java: getTradingAccounts()

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10

      private static final Empty EMPTY = Empty.getDefaultInstance();

    private final AccountServiceGrpc.AccountServiceBlockingStub accountServiceBlockingStub;

    private TradingAccounts getTradingAccounts() {
      AccessTokenRequest request = AccessTokenRequest.newBuilder()
          .setAccessToken(accessToken)
          .build();
      return accountServiceBlockingStub.getTradingAccounts(request);
    }

| Important Not all accounts in the pro version of the ActiveTrader can be used for the trading functionality. Please refer to the TradingAccount and check for the access avialibility of the selected account (flag: tradable).

| Useful Typical use case is to get this information once and keep it during one connection session.

#### Stream account information changes

To get pushed trading account information is need to subscribe an account for the trading account stream.

Example Java: streamTradingAccountInformation()

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

      private void streamTradingAccountInformation() {
      TradingAccounts tradingAccounts = getTradingAccounts(); (1)
      for (int accountIndex = 0; accountIndex<tradingAccounts.getAccountsCount(); accountIndex++) {
        TradingAccount account = tradingAccounts.getAccounts(accountIndex); (2)
        TradingAccountRequest request = TradingAccountRequest.newBuilder()
            .setAccessToken(accessToken)
            .setTradingAccount(account)
            .build();

        TradingAccountInformationObserver observer = (3)
            new TradingAccountInformationObserver(request, accountServiceStub);
        accountObservers.put(account, observer);
      }
    }

1 | Get trading accounts
2 | Iterate over each account
3 | Subscribe account

TradingAccountInformationObserver is the help class to encapsulate typical processing with the stream data.

Example Java: TradingAccountInformationObserver

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32

      import com.consorsbank.module.tapi.grpc.AccountServiceGrpc.AccountServiceStub;
    import com.consorsbank.module.tapi.grpc.account.TradingAccount;
    import com.consorsbank.module.tapi.grpc.account.TradingAccountInformation;
    import com.consorsbank.module.tapi.grpc.account.TradingAccountRequest;
    import com.consorsbank.module.tapi.grpc.common.Error;

    public class TradingAccountInformationObserver extends ServerSubscription<TradingAccount, TradingAccountInformation>{
      private final AccountServiceStub orderServiceStub;

      public TradingAccountInformationObserver(
          TradingAccountRequest request, AccountServiceStub orderServiceStub) {

        this.orderServiceStub = orderServiceStub;
        this.orderServiceStub.streamTradingAccount(request, this); (1)
      }

      @Override
      public void onCompleted() { (2)
        System.out.println("Call completed!");
      }

      @Override
      public void onNext(TradingAccountInformation reply) { (3)
        Error error = reply.getError(); (4)
        if (error==Error.getDefaultInstance()) {
          System.out.printf("Async trading information: %s%n", reply);
        } else {
          System.out.printf("Error: %s%n", error);
        }
      }
    }

1 | Subscribe for account information
2 | Called on the completting subscription
3 | Called on the account information change
4 | Check for an error

ServerSubscription contains functions to control streaming of the data. If, for example, you don’t need to recieve data from any subscription, you can unsubscribe it with help of close function.

Example Java: ServerSubscription

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27

      import io.grpc.Status;
    import io.grpc.StatusRuntimeException;
    import io.grpc.stub.ClientCallStreamObserver;
    import io.grpc.stub.ClientResponseObserver;

    public abstract class ServerSubscription<R, T> implements ClientResponseObserver<R, T>, Closeable {
      private ClientCallStreamObserver<R> observer;

      /**
       * This function is called during subscription initialization.
       * observer will created by GRPC engine and can be used for
       * data flow control.
       */
      @Override
      public void beforeStart(ClientCallStreamObserver<R> observer) {
        this.observer = observer; (1)
      }

      /**
       * Call this function to unsubscribe from server
       */
      @Override
      public void close() {
        observer.cancel("Fin", null); (2)
      }
      // ...
    }

1 | Store client observer by initialization
2 | Stop listening events (unsubscribe from stream)

#### Stream account transactions changes

To get pushed trading account transactions list is need to subscribe account for trading account transactions stream.

Example Java: streamTradingAccountTransactions()

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

      private void streamTradingAccountTransactions() {
      TradingAccounts tradingAccounts = getTradingAccounts(); (1)
      for (int accountIndex = 0; accountIndex<tradingAccounts.getAccountsCount(); accountIndex++) {
        TradingAccount account = tradingAccounts.getAccounts(accountIndex); (2)
        TradingAccountRequest request = TradingAccountRequest.newBuilder()
            .setAccessToken(accessToken)
            .setTradingAccount(account)
            .build();
        TradingAccountTransactionsObserver observer = (3)
            new TradingAccountTransactionsObserver(request, accountServiceStub);
        accountTransactionsObservers.put(account, observer);
      }
    }

1 | Get trading accounts
2 | Iterate over each account
3 | Subscribe account

Example Java: TradingAccountTransactionsObserver

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35

      import com.consorsbank.module.tapi.grpc.AccountServiceGrpc.AccountServiceStub;
    import com.consorsbank.module.tapi.grpc.account.TradingAccount;
    import com.consorsbank.module.tapi.grpc.account.TradingAccountRequest;
    import com.consorsbank.module.tapi.grpc.account.TradingAccountTransactions;
    import com.consorsbank.module.tapi.grpc.account.TradingAccountTransactions.Transaction;
    import com.consorsbank.module.tapi.grpc.common.Error;

    public class TradingAccountTransactionsObserver extends ServerSubscription<TradingAccount, TradingAccountTransactions>{
      private final AccountServiceStub orderServiceStub;

      public TradingAccountTransactionsObserver(
          TradingAccountRequest request, AccountServiceStub orderServiceStub) {

        this.orderServiceStub = orderServiceStub;
        this.orderServiceStub.streamTradingAccountTransactions(request, this); (1)
      }

      @Override
      public void onCompleted() { (2)
        System.out.println("Call completed!");
      }

      @Override
      public void onNext(TradingAccountTransactions transactions) { (3)
        Error error = transactions.getError(); (4)
        if (error==Error.getDefaultInstance()) {
          System.out.printf("Async trading transactions: %s%n", transactions);
          TradingAccount account = transactions.getAccount();
          List<Transaction> transactionsList = transactions.getTransactionsList();
          // ...
        } else {
          System.out.printf("Error: %s%n", error);
        }
      }
    }

1 | Subscribe for the account information
2 | Called on the completting subscription
3 | Called on the account transactions change
4 | Check for an error

### Stock exchange service

StockExchange service provides access to the stock exchanges.

Table 3. StockExchangeService
Function | Description
--- | ---
StockExchangeDescriptions = GetStockExchanges(AccessTokenRequest) | Gets predefined stockexchages @return StockExchangeDescriptions list of stock exchange informations
StockExchangeDescription = GetStockExchange(StockExchangeRequest) | Gets specific stock exchange @param StockExchange Requested stock exchange @return StockExchangeDescription Stock exchange information

#### Get information about all stock exchanges

TAPI has list of predefined stock exchanges that can be fetched directly. Each stock exchange has id and optional issuer. Some stock exchanges have identical id’s, but different issuers. For examples:

id | issuer | shortcut id | stock exchange name
--- | --- | --- | ---
ETR |  | ETR | Xetra
OTC | BAAD | BAA | Baada bank on OTC
OTC | 7649 | LUS | Lang und Schwarz
OTC | 7004 |  | Commerzbank
OTC |  | OTC | Any issuer on OTC

| Useful It’s possible to use shortcut id, if it exists, to access to the same stock exchange. For example stock exchange ("OTC", "BAAD") equivalent to the stock exchange ("BAA","")

These stock exchanges can be requested with help of Get Stock Exchanges function. As a result will delivered stock exchanges with names.

Example Java: getStockExchanges()

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10

      private static final Empty EMPTY = Empty.getDefaultInstance();

    private final StockExchangeServiceGrpc.StockExchangeServiceBlockingStub stockExchangeServiceBlockingStub;

    private StockExchangeDescriptions getStockExchanges() {
      AccessTokenRequest request = AccessTokenRequest.newBuilder()
          .setAccessToken(accessToken)
          .build();
      return stockExchangeServiceBlockingStub.getStockExchanges(request);
    }

| Useful This information can be stored and reused in the user application.

#### Get information about specific stock exchange

It’s also possible to get information about one specific stock exchange. Next example shows how to request stock exchange information about Baada issuer on the OTC:

Example Java: getBaadaStockExchangeInformation()

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

      private StockExchangeDescription getBaadaStockExchangeInformation() {
      StockExchange stockExchange = StockExchange.newBuilder()
          .setId("OTC")
          .setIssuer("BAAD")
          .build(); (1)

      StockExchangeRequest request = StockExchangeRequest.newBuilder()
          .setAccessToken(accessToken)
          .setStockExchange(stockExchange)
          .build(); (2)
      return stockExchangeServiceBlockingStub.getStockExchange(request); (3)
    }

1 | Prepare Baada on OTC stock exchange
2 | Build request
3 | Request information about stock exchange

### Depot service

With help of the depot service is possible to stream information about depot entries. Depot service has next functions:

#### Stream depot changes

Table 4. DepotService
Function | Description
--- | ---
DepotEntries ⇐ StreamDepot(TradingAccountRequest) | Subscribes one trading account for the depot data updates @param TradingAccount Trading account for push @stream DepotEntries depot entries linked to the account
Empty = UpdateDepot(TradingAccountRequest) | Initiates depot update action. All changes come by the StreamDepot subscription. This function doesn’t wait for the action result. @param TradingAccount Trading account for update

Example Java: streamDepotData()

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

      private final DepotServiceGrpc.DepotServiceStub depotServiceStub;

    private void streamDepotData() {
      TradingAccounts tradingAccounts = getTradingAccounts(); (1)
      for (int accountIndex = 0; accountIndex<tradingAccounts.getAccountsCount(); accountIndex++) {
        TradingAccount account = tradingAccounts.getAccounts(accountIndex);

        TradingAccountRequest request = TradingAccountRequest.newBuilder()
            .setAccessToken(accessToken)
            .setTradingAccount(account)
            .build();

        DepotObserver depotObserver = new DepotObserver(request, depotServiceStub); (2)
        depotObservers.put(account, depotObserver);
      }
    }

1 | Get trading accounts
2 | Greate depot observer for each account

Update events are delivered on each depot entry change and contain information about whole depot.

Example Java: DepotObserver

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28

      public class DepotObserver extends ServerSubscription<TradingAccountRequest, DepotEntries>{
      private final DepotServiceStub serviceStub;

      public DepotObserver(TradingAccountRequest request, DepotServiceStub depotServiceStub) {
        this.serviceStub = depotServiceStub;
        this.serviceStub.streamDepot(request, this); (1)
      }

      @Override
      public void onCompleted() { (2)
        System.out.println("Call completed!");
      }

      @Override
      public void onNext(DepotEntries depotEntries) { (3)
        Error error = depotEntries.getError(); (4)
        if (error==Error.getDefaultInstance()) {
          System.out.printf("Async depot: %s%n", depotEntries);
          TradingAccount account = depotEntries.getAccount();
          List<DepotEntry> entriesList = depotEntries.getEntriesList();
          // ...

        } else {
          System.out.printf("Error: %s%n", error);
        }
      }
    }

1 | Subscribe for the depot data
2 | Called on the completing subscription
3 | Called on the depot entries change
4 | Check for an error

#### Update depot

Sometime is necessary to update depot manually. To initiate this update you have to call UpdateDepot function. This function takes trading account as input parameter and doesn’t deliver any results. It’s also don’t wait for the results. All changes are delivered directly to the depot listeners in the background.

| Warning This function used for the compatibility proposals and can be removed in the future versions of the TAPI.

### Security service

#### Securities access

All securities can be accessed with help of security codes. Typical trading securities codes are WKN and ISIN. TAPI is able to operate with additional security code types:

Security code type | Tradable | Description
--- | --- | ---
WKN | Yes | WKN
ISIN | Yes | ISIN
ID_NOTATION | No | FactSet id notation
ID_OSI | No | FactSet id osi
ID_INSTRUMENT | No | FactSet id instrument
MNEMONIC | No | German short id
MEMONIC_US | No | US short id (only for us instruments)

Security code can be created with help of next code.

Example Java: getSecurityCode()

      1
    2
    3
    4
    5
    6

      public static SecurityCode getSecurityCode(String code, SecurityCodeType codeType) {
      return SecurityCode.newBuilder() (1)
          .setCode(code) (2)
          .setCodeType(codeType==null ? SecurityCodeType.NO_CODE_TYPE : codeType) (3)
          .build(); (4)
    }

1 | Create builder for SecurityCode object
2 | Set security code
3 | Set security code type (WKN, ISIN, . . .)
4 | Build immutable SecurityCode object

| Important In some cases TAPI can guess security code type by input security code value. In this case the security code type should be set to NO_CODE_TYPE value. Please care that’s not guaranty right detection of the security code. The good practice is to use security code type by the building of the security code object.

Security service contains next functions:

Table 5. SecurityService
Function | Description
--- | ---
SecurityInfoReply = GetSecurityInfo(SecurityInfoRequest) | Gets security information about security @param SecurityInfoRequest Request object with interested security @return SecurityInfoReply Complete information about security
SecurityMarketDataReply ⇐ StreamMarketData(SecurityMarketDataRequest) | Subscribes security with stock exchange for market data updates @param SecurityMarketDataRequest Market data request with interested security and stock exchange @stream SecurityMarketDataReply Reply with all market data values
SecurityOrderBookReply ⇐ StreamOrderBook(SecurityOrderBookRequest) | Subscribes security with stock exchange for orderbook updates @param SecurityOrderBookRequest Orderbook data request with interested security and stock exchange @stream SecurityOrderBookReply Reply with all orderbook values
CurrencyRateReply ⇐ StreamCurrencyRate(CurrencyRateRequest) | Subscribes for currency rate from one currency to another currency. @param SecurityOrderBookRequest currency rate request with interested currencies from/to @stream CurrencyRateReply reply with currency rate
SecurityPriceHistoryReply = GetSecurityPriceHistory(SecurityPriceHistoryRequest) | Requests history data for one security on one stockexchange in intraday or historical format @param SecurityPriceHistoryRequest Data with security, stockexchange, how many days and resolution @return SecurityPriceHistoryReply List of the historical quotes or an error

#### Get security information

Security information can be requested with help of GetSecurityInfo function. As a result will delivered security name, class, codes and stock exchanges with trading possibilites. This information can be used by the ordering. It also contains data about tradabity on the different markets and by different issuers. The flags LimitToken with values QUOTE_ONLY and LIMIT_AND_QUOTE show if for the security is possible to use quote buy and sell on the selected market by the selected issuer. For more information please see GetQuote and AcceptQuote functions.

Example Java: requestSecurityInfo()

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

      private final SecurityServiceGrpc.SecurityServiceBlockingStub securityServiceBlockingStub;

    private SecurityInfoReply requestSecurityInfo(String code, SecurityCodeType securityCodeType) {
      SecurityCode securityCode = TestUtils.getSecurityCode(code, securityCodeType); (1)
      SecurityInfoRequest request = SecurityInfoRequest.newBuilder() (2)
          .setAccessToken(accessToken)
          .setSecurityCode(securityCode) (3)
          .build(); (4)
      SecurityInfoReply response = securityServiceBlockingStub.getSecurityInfo(request); (5)
      return response;
    }

1 | Create security code object
2 | Create builder for SecurityinfoRequest object
3 | Set security code
4 | Build immutable SecurityinfoRequest object
5 | Request security information

#### Stream market data information

To get pushed market data (push courses) is need to subscribe security and stock exchange for this information with help of StreamMarketData function. SecurityMarketDataReply contains all values, which were changed.

Example Java: streamMarketData()

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

      private final SecurityServiceGrpc.SecurityServiceStub securityServiceStub;

    private MarketDataDataObserver streamMarketData(String code,
        SecurityCodeType securityCodeType, String stockExchangeId, String currency) {

      SecurityWithStockExchange securityWithStockExchange = (1)
          TestUtils.getSecurityWithStockExchange(code, securityCodeType, stockExchangeId, null);

      SecurityMarketDataRequest request =  SecurityMarketDataRequest.newBuilder()
          .setAccessToken(accessToken)
          .setSecurityWithStockexchange(securityWithStockExchange) (2)
          .setCurrency(currency!=null ? currency : "")
          .build();

      MarketDataDataObserver marketDataDataObserver = (3)
          new MarketDataDataObserver(request, securityServiceStub);

      String key = code+"|"+securityCodeType+"|"+stockExchangeId+"|"+currency;
      marketDataObservers.put(key, marketDataDataObserver);
      return marketDataDataObserver;
    }

1 | Prepare security with stock exchange
2 | Prepare request
3 | Greate MarketDataDataObserver to subscribe market data information

Update events deliver changed market data values.

To subscribe for the market data information it is necessary to create SecurityWithStockExchange object.

Example Java: getSecurityWithStockExchange()

      1
    2
    3
    4
    5
    6
    7
    8

      public static SecurityWithStockExchange getSecurityWithStockExchange(
        SecurityCode securityCode, StockExchange stockExchange) {

      return SecurityWithStockExchange.newBuilder() (1)
          .setSecurityCode(securityCode) (2)
          .setStockExchange(stockExchange) (3)
          .build(); (4)
    }

1 | Create builder for SecurityWithStockExchange object
2 | Set security code
3 | Set stock exchange
4 | Build immutable SecurityWithStockExchange object

You have to prepare StockExchange object.

Example Java: getStockExchange()

      1
    2
    3
    4
    5
    6
    7
    8

      public static StockExchange getStockExchange(String stockExchangeId, String issuer) {
      Builder stockBuilder = StockExchange.newBuilder(); (1)
      if (issuer!=null) {
        stockBuilder.setIssuer(issuer); (2)
      }
      return stockBuilder.setId(stockExchangeId) (3)
          .build(); (4)
    }

1 | Create builder for StockExchange object
2 | Set issuer
3 | Set stock exchange id
4 | Build immutable StockExchange object

Example Java: MarketDataDataObserver

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31

      public class MarketDataDataObserver extends ServerSubscription<SecurityMarketDataRequest, SecurityMarketDataReply> {
      private final SecurityServiceStub securityServiceStub;

      public MarketDataDataObserver(SecurityMarketDataRequest request,
          SecurityServiceStub securityServiceStub) {

        this.securityServiceStub = securityServiceStub;

        securityServiceStub.streamMarketData(request, this); (1)
      }

      @Override
      public void onCompleted() {
        System.out.println("Call completed!"); (2)
      }

      @Override
      public void onNext(SecurityMarketDataReply response) {
        Error error = response.getError();
        if (error==Error.getDefaultInstance()) { (3)
          System.out.printf("Async client onNext: %s%n", response);
          double lastPrice = response.getLastPrice();
          Timestamp lastDateTime = response.getLastDateTime();
          // ...

        } else {
          System.out.printf("Error: %s%n", error);
        }
      }
    }

1 | Subscribe for the market data
2 | Called of complete subscription
3 | Process madret data events

#### Stream orderbook data

To get pushed orderbook data (second level push courses) is need to subscribe security and stockexchange for this information with help of StreamOrderBook function. SecurityOrderBookReply contains actual orderbook values. To create SecurityOrderBookRequest is need to create SecurityWithStockExchange object first. Currently order book data supported only on Xetra stock exchange.

Example Java: streamOrderBook()

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

      private final SecurityServiceGrpc.SecurityServiceStub securityServiceStub;

    private OrderBookDataObserver streamOrderBook(String code,
        SecurityCodeType securityCodeType, String stockExchangeId, String currency) {

      SecurityWithStockExchange securityWithStockExchange =  (1)
          TestUtils.getSecurityWithStockExchange(code, securityCodeType, stockExchangeId, null);

      SecurityOrderBookRequest request = SecurityOrderBookRequest.newBuilder()
          .setAccessToken(accessToken)
          .setSecurityWithStockexchange(securityWithStockExchange)
          .setCurrency(currency==null ? "" : currency)
          .build(); (2)

      OrderBookDataObserver orderBookDataObserver =  (3)
          new OrderBookDataObserver(request, securityServiceStub);

      String key = code+"|"+securityCodeType+"|"+stockExchangeId+"|"+currency;
      orderBookObservers.put(key, orderBookDataObserver);
      return orderBookDataObserver;
    }

1 | Prepare security with stock exchange
2 | Prepare request
3 | Greate OrderBookData observer to subscribe orderbook information

Example Java: OrderBookDataObserver

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32

      public class OrderBookDataObserver extends ServerSubscription<SecurityOrderBookRequest, SecurityOrderBookReply> {
      private final SecurityServiceStub securityServiceStub;

      public OrderBookDataObserver(SecurityOrderBookRequest request,
          SecurityServiceStub securityServiceStub) {
        this.securityServiceStub = securityServiceStub;

        securityServiceStub.streamOrderBook(request, this); (1)
      }

      @Override
      public void onCompleted() {
        System.out.println("Call completed!"); (2)
      }

      @Override
      public void onNext(SecurityOrderBookReply response) {
        Error error = response.getError();
        if (error==Error.getDefaultInstance()) {
          System.out.printf("Async client onNext: %s%n", response); (3)
          List<OrderBookEntry> orderBookEntriesList = response.getOrderBookEntriesList();
          for (OrderBookEntry orderBookEntry : orderBookEntriesList) {
            double askPrice = orderBookEntry.getAskPrice();
            double askVolume = orderBookEntry.getAskVolume();
          }
          // ...

        } else {
          System.out.printf("Error: %s%n", error);
        }
      }
    }

1 | Subscribe for orderbook data
2 | Called on complete subscription
3 | Process order book events

#### Stream currency rate

It is possible to get pushed currency rate from one currency to other. This information can be used for the realtime convertation of the money values.

| Important For the market data quotes / order books it is possible to define target currency. It this case the convertation will be processed automatically.

Example Java: streamCurrencyRate(String currencyFrom, String currencyTo)

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

      private final SecurityServiceGrpc.SecurityServiceStub securityServiceStub;

    private CurrencyRateDataObserver streamCurrencyRate(String currencyFrom, String currencyTo) {
      CurrencyRateRequest request = CurrencyRateRequest.newBuilder()
          .setAccessToken(accessToken)
          .setCurrencyFrom(currencyFrom)
          .setCurrencyTo(currencyTo)
          .build(); (1)

      CurrencyRateDataObserver currencyRateDataObserver = (2)
          new CurrencyRateDataObserver(request, securityServiceStub);

      String key = currencyFrom+"|"+currencyTo;
      currencyObservers.put(key, currencyRateDataObserver);
      return currencyRateDataObserver;
    }

1 | Greate request
2 | Greate CurrencyRateData observer to subscribe currency rate

Example Java: CurrencyRateDataObserver

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30

      public class CurrencyRateDataObserver extends ServerSubscription<CurrencyRateRequest, CurrencyRateReply> {
      private final SecurityServiceStub securityServiceStub;

      public CurrencyRateDataObserver(CurrencyRateRequest request,
          SecurityServiceStub securityServiceStub) {

        this.securityServiceStub = securityServiceStub;

        securityServiceStub.streamCurrencyRate(request, this); (1)
      }

      @Override
      public void onCompleted() {
        System.out.println("Call completed!"); (2)
      }

      @Override
      public void onNext(CurrencyRateReply response) {
        Error error = response.getError();
        if (error==Error.getDefaultInstance()) {
          System.out.printf("Async client onNext: %s%n", response);
          double currencyRate = response.getCurrencyRate(); (3)
          // ...

        } else {
          System.out.printf("Error: %s%n", error);
        }
      }
    }

1 | Subscribe for currency rate
2 | Called on complite subscription
3 | Process currency rate events

#### Get security historic data

Security historic data can be requested with help of getSecurityPriceHistory() function. As a result will delivered security with stock exchange, currency, historic data list. The parameter days defines how many trading day will be requested. For intraday types of the time resolution this value should be 15 or less. Be careful the amount of the data can be very big, especialy for intraday data with tick resolution.

Example Java: getSecurityPriceHistory()

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

      private final SecurityServiceGrpc.SecurityServiceBlockingStub securityServiceBlockingStub;

    private SecurityPriceHistoryReply getSecurityPriceHistory(
        String code, SecurityCodeType securityCodeType, String stockExchangeId,
        int days, TimeResolution resolution) {

      SecurityWithStockExchange securityWithStockExchange =  (1)
          TestUtils.getSecurityWithStockExchange(code, securityCodeType, stockExchangeId, null);
      SecurityPriceHistoryRequest request = SecurityPriceHistoryRequest.newBuilder() (2)
          .setAccessToken(accessToken)
          .setSecurityWithStockexchange(securityWithStockExchange) (3)
          .setDays(days) (4)
          .setTimeResolution(resolution) (5)
          .build(); (6)
      SecurityPriceHistoryReply response =
          securityServiceBlockingStub.getSecurityPriceHistory(request); (7)
      return response;
    }

1 | Create security with stock exchange object
2 | Create builder for SecurityPriceHistoryRequest object
3 | Set security with stock exchange
4 | Set days number
5 | Set time resolution (tick, minute, etc)
6 | Build immutable SecurityPriceHistoryRequest object
7 | Request historic data

| Important Last example will block program execution until the result is returned. Sometimes to avoid timeouts by the listening it’s better to use non blocking calls.

### Order service

With help of the order service is possible to execute, change, activate, deactivate or cancel orders. It’s also allow to listen for the orders and to control them asyncronically.

#### Order types and parameters

TAPI allowes to execute different order types on the stock exchanges with different parameters. Next tables shows what parameters are necessary (x) and optional (o) depends from selected stock exchange and order model. The full list of order possibilites is delivered by the GetSecurityInformation function.

Parameter \ Order model | Market | Limit | StopMarket | StopLimit | OneCancelsOtherMarket | OneCancelsOtherLimit | TrailingStopMarket | TrailingStopLimit
--- | --- | --- | --- | --- | --- | --- | --- | ---
account_number | x | x | x | x | x | x | x | x
security_with_stockexchange | x | x | x | x | x | x | x | x
order_type | x | x | x | x | x | x | x | x
amount | x | x | x | x | x | x | x | x
order_supplement | o, 1) | o, 1) |  |  |  |  |  |
validity_date | x | x | x | x | x | x | x | x
limit |  | x |  |  | x | x |  |
stop |  |  | x | x | x | x | x | x
stop_limit |  |  |  | x |  | x |  |
trailing_distance |  |  |  |  |  |  | x | x
trailing_notation |  |  |  |  |  |  | x | x
trailing_limit_tolerance |  |  |  |  |  |  |  | x, 2)
dripping_quantity | o, 3) | o, 3) |  |  |  |  |  |
position_id | o, 4) | o, 4) | o, 4) | o, 4) | o, 4) | o, 4) | o, 4) | o, 4)
validation | o ,5) | o ,5) | o ,5) | o ,5) | o ,5) | o ,5) | o ,5) | o ,5)
cash_quotation | o, 6) | o, 6) | o, 6) | o, 6) | o, 6) | o, 6) | o, 6) | o, 6)
risk_class_override | o | o | o | o | o | o | o | o
target_market_override | o | o | o | o | o | o | o | o
tax_nontransparent_override | o | o | o | o | o | o | o | o
accept_additional_fees | o | o | o | o | o | o | o | o
closed_realestate_fond_override | o | o | o | o | o | o | o | o

1 | Stock exchange: ETR only, values: IMMIDIATE_OR_CANCEL, FILL_OR_KILL, ICEBERG
2 | Stock exchange: TRG only
3 | Stock exchange: ETR only, when order_supplement equals ICEBERG, pro only
4 | Position id is optional field by the order action with existing depot position
5 | Default value: WITHOUT_VALIDATION. Order is routed directly to market
6 | Cash quotation:

Stock exchange | NOTHING | KASSA | AUCTION | OPENING | INTRADAY | CLOSING
--- | --- | --- | --- | --- | --- | ---
ETR | x | x | x | x | x | x
German | x | x |  |  |  |
Other | x |  |  |  |  |

The full list of the order service functions can be checked in the next list. Some functionality avialable only in pro version of the ActiveTrader.

| Important To execute new order is need at least to fill all madatory fields. See x values in the each column for selected order model.

Example Java: OneCancelOtherMarket order

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

      SecurityWithStockExchange securityWithStockExchange = TestUtils.getSecurityWithStockExchange("710000", SecurityCodeType.WKN, "ETR", null);

    //
    AddOrderRequest addRequest = AddOrderRequest.newBuilder() (1)
        .setOrderModel(OrderModel.ONE_CANCELS_OTHER_MARKET) (2)
        .setAccountNumber(account.getAccountNumber())
        .setSecurityWithStockexchange(securityWithStockExchange)
        .setAmount(1)
        .setValidation(Validation.VALIDATE_ONLY)
        .setLimit(39)
        .setStop(40)
        .setOrderType(OrderType.BUY)
        .setValidityDate(TestUtils.getDate(LocalDate.now())) // today
        .build();
    OrderReply addReply = getOrdersBlockingStub().addOrder(addRequest); (3)

1 | Fill mandatory parameters
2 | OneCancelOtherMarket order and it’s parameters
3 | Process order

#### Stream orders

To get information about current orders ist need to subscribe for this information with help of StreamOrders function. All order changes will come asynchronically as a list of the all avialable orders.

| Useful An amount of the updated orders can be configured in the ActiveTrader general settings.

Example Java: streamOrders()

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

      private final OrderServiceGrpc.OrderServiceStub orderServiceStub;

    private void streamOrders() {
      TradingAccounts tradingAccounts = getTradingAccounts(); (1)
      for (int accountIndex = 0; accountIndex<tradingAccounts.getAccountsCount(); accountIndex++) {
        TradingAccount account = tradingAccounts.getAccounts(accountIndex); (2)
        TradingAccountRequest request = TradingAccountRequest.newBuilder()
            .setAccessToken(accessToken)
            .setTradingAccount(account)
            .build();
        OrdersObserver ordersObserver = new OrdersObserver(request, orderServiceStub); (3)
        ordersObservers.put(account, ordersObserver);
      }
    }

1 | Get trading accounts
2 | Iterate over each account
3 | Subscribe account

Example Java: OrdersObserver

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34

      import com.consorsbank.module.tapi.grpc.OrderServiceGrpc.OrderServiceStub;
    import com.consorsbank.module.tapi.grpc.account.TradingAccount;
    import com.consorsbank.module.tapi.grpc.account.TradingAccountRequest;
    import com.consorsbank.module.tapi.grpc.common.Error;
    import com.consorsbank.module.tapi.grpc.order.Order;
    import com.consorsbank.module.tapi.grpc.order.Orders;

    public class OrdersObserver extends ServerSubscription<TradingAccount, Orders>{
      private final OrderServiceStub orderServiceStub;

      public OrdersObserver(TradingAccountRequest request, OrderServiceStub orderServiceStub) {
        this.orderServiceStub = orderServiceStub;
        this.orderServiceStub.streamOrders(request, this); (1)
      }

      @Override
      public void onCompleted() { (2)
        System.out.println("Call completed!");
      }

      @Override
      public void onNext(Orders orders) { (3)
        Error error = orders.getError(); (4)
        if (error==Error.getDefaultInstance()) {
          System.out.printf("Async orders: %s%n", orders);
          TradingAccount account = orders.getAccount();
          List<Order> ordersList = orders.getOrdersList();
          // ...

        } else {
          System.out.printf("Error: %s%n", error);
        }
      }
    }

1 | Subscribe for the order data
2 | Called on the completing subscription
3 | Called on the depot entries change
4 | Check for an error

| Important In the pro version of the ActiveTrader order number value can be changed (for example after activation / deactivation of the order). To match saved in the client application orders with the orders from update is need to use unique_id field from the Order object.

#### Update orders

Sometime is necessary to update orders manually. To initiate this update you have to call UpdateOrders function. This function takes trading account as input parameter and doesn’t deliver any results. It’s also don’t wait for the results. All changes are delivered directly to the orders listeners in the background.

| Warning This function used for the compatibility proposals and can be removed in the future versions of the TAPI.

#### Get securities quotes

Before to execute order add action is often necessary to get actual quote information for the selected security. This information can be subscribed in the security service or requested in the order service. It’s not a matter where this information is requested for the normal order add action, but it’s important in case if you want to process accept quote on the short term market. In this case is necessary to use get quote function from order service.

| Important Please call get quote function before to call of the accept order action.

Example Java: requestQuotesDirect()

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20

      private void requestQuotesDirect(String code, SecurityCodeType securityCodeType) {
      QuoteRequest quoteRequest = QuoteRequest.newBuilder()
          .setAccessToken(accessToken)
          .setOrderType(OrderType.BUY) (1)
          .setSecurityCode(TestUtils.getSecurityCode(code, securityCodeType)) (2)
          .setAmount(10) (3)
          .addStockExchanges(TestUtils.getStockExchange("BAA", null)) (4)
          .addStockExchanges(TestUtils.getStockExchange("OTC", null))
          .addStockExchanges(TestUtils.getStockExchange("TRG", null))
          .build();
      QuoteReply quoteReply = orderServiceBlockingStub.getQuote(quoteRequest); (5)
      if (quoteReply.getError()!=Error.getDefaultInstance()) {
        List<QuoteEntry> priceEntriesList = quoteReply.getPriceEntriesList(); (6)
        for (QuoteEntry quoteEntry : priceEntriesList) {
          if (quoteEntry.getError()!=Error.getDefaultInstance()) {
            // ...
          }
        }
      }
    }

1 | Set order type
2 | Set security code
3 | Set amount for the ordering
4 | Set requestes stock exchanges
5 | Request quotes with help of the blocking stub
6 | Process results

Other difference between quotes from the security service and order service is that it’s depended from user rights. An order service can have limited amount of the requests for the long terms stockexchanges. You can request data more then from one stock exchange for one security at once. In this case function returns all results for all requested stock exchanges after processing of all data for each stock exchange. That can follow to the timeouts by the functions calls. You can use asychronical requests if to don’t have timeouts is important. It’s also possible to process many get quote requests in parallel and pack to each request only one stockexchange. The results from the requests can be processed in background.

Example Java: requestQuotesAsynchronically()

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44

      private void requestQuotesAsynchronically(String code, SecurityCodeType securityCodeType) {
      final StreamObserver<QuoteReply> quotesObserver = new StreamObserver<QuoteReply>() { (1)
        @Override
        public void onNext(QuoteReply quoteReply) {
          System.err.println(quoteReply); (2)
          if (quoteReply.getError()!=Error.getDefaultInstance()) {
            List<QuoteEntry> priceEntriesList = quoteReply.getPriceEntriesList();
            // priceEntriesList will contain only one entry
            for (QuoteEntry quoteEntry : priceEntriesList) {
              StockExchange stockExchange = quoteEntry.getStockExchange();
              if (quoteEntry.getError()!=Error.getDefaultInstance()) {
                // ...
              }
            }
          }
        }
        @Override
        public void onError(Throwable t) {
          t.printStackTrace();
        }
        @Override
        public void onCompleted() {}
      };
      final SecurityCode securityCode = TestUtils.getSecurityCode(code, securityCodeType); (3)
      final StockExchange[] stockexchanges = { (4)
          TestUtils.getStockExchange("BAA", null),
          TestUtils.getStockExchange("OTC", null),
          TestUtils.getStockExchange("TRG", null),
      };

      // Request data
      for (StockExchange stockExchange : stockexchanges) {
        QuoteRequest quoteRequest = QuoteRequest.newBuilder() (5)
            .setAccessToken(accessToken)
            .setOrderType(OrderType.BUY)
            .setSecurityCode(securityCode)
            .setAmount(10)
            .addStockExchanges(stockExchange)
            .build();
        orderServiceStub.getQuote(quoteRequest, quotesObserver);
      }

      // ...
    }

1 | Prepare listener
2 | Process results in the background
3 | Prepare security code
4 | Prepare stock exchanges
5 | Request quotes with help of the non blocking stub

#### Accept quote

To place an order on the short term market is necessary to request quote first. If QuoteEntry will contain filled quote_reference field then it’s possible to place order with help of accept quote function to the short term market. Otherwise accept quote is not possible. By the calling of the accept quote function you have to use same parameters as you used for the get quote. Otherwise the request parameters will be denied and the action will be finished with an error.

Example Java: acceptQuote()

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36

      private void acceptQuote() {
      QuoteRequest quoteRequest = QuoteRequest.newBuilder() (1)
          .setAccessToken(accessToken)
          .setOrderType(OrderType.BUY)
          .setSecurityCode(TestUtils.getSecurityCode("710000", SecurityCodeType.WKN))
          .setAmount(10)
          .addStockExchanges(TestUtils.getStockExchange("OTC", null))
          .build();

      PerformanceCounter pcGetQuote = new PerformanceCounter("GetQuote");
      QuoteReply quoteReply = orderServiceBlockingStub.getQuote(quoteRequest); (2)
      pcGetQuote.print();

      if (quoteReply.getError()==Error.getDefaultInstance()) {
        QuoteEntry quoteEntry = quoteReply.getPriceEntries(0); (3)
        if (quoteEntry.getError()==Error.getDefaultInstance() &&
            !quoteEntry.getQuoteReference().isEmpty()) { (4)
          SecurityWithStockExchange securityWithStockExchange = (5)
              TestUtils.getSecurityWithStockExchange(
                  quoteReply.getSecurityCode(), quoteEntry.getStockExchange());

          AcceptQuoteRequest acceptQuoteRequest = AcceptQuoteRequest.newBuilder() (6)
              .setAccessToken(accessToken)
              .setOrderType(OrderType.BUY)
              // .setAccountNumber(accountNumber)
              .setSecurityWithStockexchange(securityWithStockExchange)
              .setAmount(10)
              .setValidation(Validation.VALIDATE_ONLY) (7)
              .setLimit(quoteEntry.getBuyPrice())
              .setQuoteReference(quoteEntry.getQuoteReference()) (8)
              .build();
          OrderReply acceptQuote = orderServiceBlockingStub.acceptQuote(acceptQuoteRequest); (9)
          System.err.println(acceptQuote);
        }
      }
    }

1 | Prepare get quote request
2 | Call get quote function
3 | Get recieved quotes (it should be only one quote, because we requested data for one stock exchange)
4 | Check if we have quote reference
5 | Prepare security with stock exchange object
6 | Preapare accept quote request
7 | Set validation flag
8 | Set to the request quote reference
9 | Call accept quote function and wait for the result

| Warning By default validation parameter equals WITHOUT_VALIDATION and accept quote request will directly routed to the market. If you want only check a validity of the request, then you need to set validation parameter to VALIDATE_ONLY. An order will validated by the backend system, but will not be routed to the market. It’s very useful for the test goals. Order number in the reply in this case is undefined.

#### Add order

To put new order to the long term marken is necessary to use AddOrder function. This function takes AddOrderRequest as an input parameter and returns OrderReply as a result. Typically this function is called with blocked stub, but it can also used with non blocking stub if more then one order need to executed in parallel.

The possible parameter combinations can be fetched from security information reply. There are defined order possibilities for defined markets.

Pro version of the ActiveTrader allowes to use additional flag inactive. If this flag set to the value true then order is placed to the system, but isn’t routed to the market. With the help of ActivateOrder function an order can be activated.

| Important It’s important to fill only parameters that need for the order execution

Example Java: addOrder()

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23

      private final OrderServiceGrpc.OrderServiceBlockingStub orderServiceBlockingStub;

    private OrderReply addOrder() {
      SecurityCode securityCode = TestUtils.getSecurityCode("710000", SecurityCodeType.WKN); (1)
      StockExchange stockExchange = TestUtils.getStockExchange("OTC", null); (2)
      SecurityWithStockExchange securityWithStockExchange =
          TestUtils.getSecurityWithStockExchange(securityCode, stockExchange); (3)
      AddOrderRequest request = AddOrderRequest.newBuilder() (4)
          .setAccessToken(accessToken)
          .setAccountNumber("123456789") (5)
          .setSecurityWithStockexchange(securityWithStockExchange)
          .setValidation(Validation.VALIDATE_ONLY) (6)
          .setAmount(1)
          .setOrderModel(OrderModel.LIMIT) (7)
          .setLimit(1)
          .setOrderType(OrderType.BUY) (8)
          .setCashQuotation(CashQuotation.KASSA)
          .setValidityDate(TestUtils.getDate(GregorianCalendar.getInstance()))
          .build();
      OrderReply addOrderReply = orderServiceBlockingStub.addOrder(request); (9)
      System.err.println(addOrderReply);
      return addOrderReply;
    }

1 | Prepare security code
2 | Prepare stock exchange
3 | Prepare security with stock exchange
4 | Prepare request
5 | Set trading account
6 | Set validation flag
7 | Set order limit
8 | Set order type
9 | Process order add

| Warning By default validation parameter equals WITHOUT_VALIDATION and accept quote request will directly routed to the market. If you want only check a validity of the request, then you need to set validation parameter to VALIDATE_ONLY. An order will validated by the backend system, but will not be routed to the market. It’s very useful for the test goals. Order number in the reply in this case is undefined.

#### Change order

To change order is necessary to have order number of existing order and an account with this order linked to. The order can be changed if the status of the orders allowes that and new state is allowed by the markt.

| Useful Sometimes can happens that order is changed / executed on the market, but status information is not delivered into the application.

Example Java: changeOrder()

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

      private final OrderServiceGrpc.OrderServiceBlockingStub orderServiceBlockingStub;

    private void changeOrder(Order order, TradingAccount account) {
      if (order!=null) {
        String orderNumber = order.getOrderNumber();
        if (orderNumber!=null && !orderNumber.isEmpty()) {
          ChangeOrderRequest changeOrderRequest = ChangeOrderRequest.newBuilder()
              .setAccessToken(accessToken)
              .setAccountNumber(account.getAccountNumber()) (1)
              .setOrderNumber(order.getOrderNumber()) (2)
              .setValidation(Validation.VALIDATE_ONLY) (3)
              .setOrderModel(OrderModel.LIMIT) (4)
              .setLimit(2)
              .build();

          OrderReply changeOrderReply = (5)
              orderServiceBlockingStub.changeOrder(changeOrderRequest);
          System.out.println(changeOrderReply);
        }
      }
    }

1 | Set account number
2 | Set order number
3 | Set validation flag
4 | Set new limit
5 | Process change order

| Warning By default validation parameter equals WITHOUT_VALIDATION and accept quote request will directly routed to the market. If you want only check a validity of the request, then you need to set validation parameter to VALIDATE_ONLY. An order will validated by the backend system, but will not be routed to the market. It’s very useful for the test goals.

#### Cancel order

To cancel order is necessary to have order number of existing order and an account with this order linked in. The order can be canceled if the status of the orders allowes that.

Example Java: cancelOrder()

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19

      private final OrderServiceGrpc.OrderServiceBlockingStub orderServiceBlockingStub;

    private void cancelOrder(Order order, TradingAccount account) {
      if (order!=null) {
        String orderNumber = order.getOrderNumber();
        if (orderNumber!=null && !orderNumber.isEmpty()) {
          CancelOrderRequest cancelOrderRequest = CancelOrderRequest.newBuilder()
              .setAccessToken(accessToken)
              .setAccountNumber(account.getAccountNumber()) (1)
              .setOrderNumber(order.getOrderNumber()) (2)
              .setValidation(Validation.VALIDATE_ONLY) (3)
              .build();

          OrderReply cancelOrderReply = (4)
              orderServiceBlockingStub.cancelOrder(cancelOrderRequest);
          System.out.println(cancelOrderReply);
        }
      }
    }

1 | Set account number
2 | Set order number
3 | Set validation flag
4 | Process change order

| Warning By default validation parameter equals WITHOUT_VALIDATION and accept quote request will directly routed to the market. If you want only check a validity of the request, then you need to set validation parameter to VALIDATE_ONLY. An order will validated by the backend system, but will not be routed to the market. It’s very useful for the test goals.

#### Activate order

Activate order function used to activate inactive order and route an order to the market. This function available only in pro version of the ActiveTrader.

Example Java: activateOrder()

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19

      private final OrderServiceGrpc.OrderServiceBlockingStub orderServiceBlockingStub;

    private void activateOrder(Order order, TradingAccount account) {
      if (order!=null) {
        String orderNumber = order.getOrderNumber();
        if (orderNumber!=null && !orderNumber.isEmpty()) {
          ActivateOrderRequest activateOrderRequest = ActivateOrderRequest.newBuilder()
              .setAccessToken(accessToken)
              .setAccountNumber(account.getAccountNumber()) (1)
              .setOrderNumber(order.getOrderNumber()) (2)
              .setValidation(Validation.VALIDATE_ONLY) (3)
              .build();

          OrderReply changeOrderReply =  (4)
              orderServiceBlockingStub.activateOrder(activateOrderRequest);
          System.out.println(changeOrderReply);
        }
      }
    }

1 | Set account number
2 | Set order number
3 | Set validation flag
4 | Process activate order

#### Deactivate order

Deactivate order function used to deactivate active order and remove an order from the market. This function available only in pro version of the ActiveTrader.

Example Java: deactivateOrder()

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19

      private final OrderServiceGrpc.OrderServiceBlockingStub orderServiceBlockingStub;

    private void deactivateOrder(Order order, TradingAccount account) {
      if (order!=null) {
        String orderNumber = order.getOrderNumber();
        if (orderNumber!=null && !orderNumber.isEmpty()) {
          DeactivateOrderRequest deactivateOrderRequest = DeactivateOrderRequest.newBuilder()
              .setAccessToken(accessToken)
              .setAccountNumber(account.getAccountNumber()) (1)
              .setOrderNumber(order.getOrderNumber()) (2)
              .setValidation(Validation.VALIDATE_ONLY) (3)
              .build();

          OrderReply changeOrderReply = (4)
              orderServiceBlockingStub.deactivateOrder(deactivateOrderRequest);
          System.out.println(changeOrderReply);
        }
      }
    }

1 | Set account number
2 | Set order number
3 | Set validation flag
4 | Process deactivate order

#### Order costs

##### BaFin Rules

The law allowes to execute orders only after requesting of the order costs with a possibility to decline order in the case if order costs are not accepted. That follows to request order cost before order execution. The order execution without requesting of the order costs is not allowed.

##### Processing of the order costs

You can request an information about estimated order costs in AddOrderRequest and AcceptQuoteRequest.

| Warning OrderCost contains only estimated values. The real values are depended from real execution quotes, time of the execution and other parameters.

To request cost information is need to execute orders requests with Validation values VALIDATE_WITH_TOTAL_COSTS, TOTAL_COST_ONLY or VALIDATE_WITH_DETAIL_COSTS. In first and second cases only total or aggregated costs are calculated. In second case detail information about costs is delivered. In all cases only validation of the request is happened, without real execution. To execute order you have to repeat same request with Validation WITHOUT_VALIDATION type.

| Important During prepartion phase TOTAL_COST_ONLY validation type can be replaced with VALIDATE_WITH_TOTAL_COSTS type.

All order costs can be checked in the online archive.

##### Error handling

If no costs are avialable or costs information is outdated then by the order execution will be return ORD_COSTS_ABSENT_ERR error. In such cases is necessary to repeat order costs request and order execution request.

| Useful To speed up order execution and save time by the order placement it’s possible to prepare and validate order with VALIDATE_WITH_TOTAL_COSTS or TOTAL_COST_ONLY flags and some time later execute the same order with WITHOUT_VALIDATION flag. The host system will recognize parameters of the order and will forward order directly to the market. Otherwise to fullfil all BaFin requirements host system will request order costs before the order execution. In the each case the information about order costs will be placed into online archive before the order execution.

| Warning This request doesn’t send order to the market, but validates only. As the result no real order is placed into the system.

Example Java: getOrderCosts()

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31

      private final OrderServiceGrpc.OrderServiceBlockingStub orderServiceBlockingStub;

    private OrderReply getOrderCosts() {
      SecurityCode securityCode = TestUtils.getSecurityCode("710000", SecurityCodeType.WKN); (1)
      StockExchange stockExchange = TestUtils.getStockExchange("OTC", null); (2)
      SecurityWithStockExchange securityWithStockExchange =
          TestUtils.getSecurityWithStockExchange(securityCode, stockExchange); (3)
      AddOrderRequest request = AddOrderRequest.newBuilder() (4)
          .setAccessToken(accessToken)
          .setAccountNumber("123456789") (5)
          .setSecurityWithStockexchange(securityWithStockExchange)
          .setValidation(Validation.VALIDATE_WITH_TOTAL_COSTS) (6)
          // .setValidation(Validation.VALIDATE_WITH_DETAIL_COSTS) (7)
          .setAmount(1)
          .setOrderModel(OrderModel.LIMIT)
          .setLimit(1)
          .setOrderType(OrderType.BUY)
          .setCashQuotation(CashQuotation.KASSA)
          .setValidityDate(TestUtils.getDate(GregorianCalendar.getInstance()))
          .build();
      OrderReply addOrderReply = orderServiceBlockingStub.addOrder(request); (8)

      OrderCosts orderCosts = addOrderReply.getOrderCosts(); (9)
      double estimatedTotalCosts = orderCosts.getEstimatedTotalCosts();
      for (CategoryCost categoryCost : orderCosts.getCategorieCostsList()) {
        double totalSumAbsolute = categoryCost.getTotalSumAbsolute();
        //
      }
      System.err.println(addOrderReply);
      return addOrderReply;
    }

1 | Prepare security code
2 | Prepare stock exchange
3 | Prepare security with stock exchange
4 | Prepare request
5 | Set order parameters
6 | Set validation with total costs
7 | Alternative: Set validation with detail costs
8 | Process order add
9 | Extract order costs

##### Early request of the order costs

| Useful It’s possible to prepare an order for the execution and keep an infomation about order costs for the future execution without additional checks. This information will be cached in the application and reused by the real order execution. No additional steps will be performed. All data about order costs will be (additionally) avialible in the online archive. It’s important to understand that sometime costs information can be absolette. In this case an order execution will be failed with the error ORD_COSTS_NOT_REQUESTED. In such cases is need to repeat order costs request and order execution request.

Example Java: addOrderWithCostsRequest()

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36

      private final OrderServiceGrpc.OrderServiceBlockingStub orderServiceBlockingStub;

    private OrderReply addOrderWithCostsRequest() {
      SecurityCode securityCode = TestUtils.getSecurityCode("710000", SecurityCodeType.WKN); (1)
      StockExchange stockExchange = TestUtils.getStockExchange("OTC", null); (2)
      SecurityWithStockExchange securityWithStockExchange =
          TestUtils.getSecurityWithStockExchange(securityCode, stockExchange); (3)
      Builder requestBuilder = AddOrderRequest.newBuilder() (4)
          .setAccessToken(accessToken)
          .setAccountNumber("123456789") (5)
          .setSecurityWithStockexchange(securityWithStockExchange)
          .setAmount(1)
          .setOrderModel(OrderModel.LIMIT)
          .setLimit(1)
          .setOrderType(OrderType.BUY)
          .setCashQuotation(CashQuotation.KASSA)
          .setValidityDate(TestUtils.getDate(GregorianCalendar.getInstance()));
      AddOrderRequest costsRequest = requestBuilder
          .setValidation(Validation.TOTAL_COSTS_ONLY) (6)
          .build();
      OrderReply costsReply = orderServiceBlockingStub.addOrder(costsRequest); (7)

      if (costsReply.getError()!=Error.getDefaultInstance()) {
        System.err.print("Error: "+costsReply.getError());
        return costsReply;
      }

      // Can be later
      AddOrderRequest executionRequest = requestBuilder
          .setValidation(Validation.WITHOUT_VALIDATION) (8)
          .build();

      OrderReply executionReply = orderServiceBlockingStub.addOrder(executionRequest); (9)
      System.err.println(executionReply);
      return executionReply;
    }

1 | Prepare security code
2 | Prepare stock exchange
3 | Prepare security with stock exchange
4 | Prepare request
5 | Set order parameters
6 | Set validation only with total costs
7 | Process costs calulation request
8 | Prepare real order add request (Warning real execution)
9 | Process order execution

Example Java: acceptQuoteWithCostsRequest()

      1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55

      private final OrderServiceGrpc.OrderServiceBlockingStub orderServiceBlockingStub;

    private void acceptQuoteWithCostsRequest() {
      SecurityCode securityCode = TestUtils.getSecurityCode("710000", SecurityCodeType.WKN);
      StockExchange stockExchange = TestUtils.getStockExchange("OTC", null);
      SecurityWithStockExchange securityWithStockExchange = TestUtils.getSecurityWithStockExchange(securityCode, stockExchange);

      AcceptQuoteRequest costsRequest = AcceptQuoteRequest.newBuilder() (1)
          .setAccessToken(accessToken)
          .setOrderType(OrderType.BUY)
          .setSecurityWithStockexchange(securityWithStockExchange)
          .setAmount(10)
          .setValidation(Validation.TOTAL_COSTS_ONLY) (2)
          //.setLimit(10) (3)
          //.setQuoteReference() (4)
          .build();
      OrderReply costsReply = orderServiceBlockingStub.acceptQuote(costsRequest); (5)

      if (costsReply.getError()!=Error.getDefaultInstance()) {
        System.err.print("Error: "+costsReply.getError());
        return;
      }

      // Later
      QuoteRequest quoteRequest = QuoteRequest.newBuilder() (6)
          .setAccessToken(accessToken)
          .setOrderType(OrderType.BUY)
          .setSecurityCode(securityCode)
          .setAmount(10)
          .addStockExchanges(stockExchange)
          .build();

      PerformanceCounter pcGetQuote = new PerformanceCounter("GetQuote");
      QuoteReply quoteReply = orderServiceBlockingStub.getQuote(quoteRequest); (7)
      pcGetQuote.print();

      if (quoteReply.getError()==Error.getDefaultInstance()) {
        QuoteEntry quoteEntry = quoteReply.getPriceEntries(0); (8)
        if (quoteEntry.getError()==Error.getDefaultInstance() &&
            !quoteEntry.getQuoteReference().isEmpty()) { (9)

          AcceptQuoteRequest acceptQuoteRequest = AcceptQuoteRequest.newBuilder() (10)
              .setAccessToken(accessToken)
              .setOrderType(OrderType.BUY)
              .setSecurityWithStockexchange(securityWithStockExchange)
              .setAmount(10)
              .setValidation(Validation.WITHOUT_VALIDATION) (11)
              .setLimit(quoteEntry.getBuyPrice())
              .setQuoteReference(quoteEntry.getQuoteReference()) (12)
              .build();
          OrderReply acceptQuote = orderServiceBlockingStub.acceptQuote(acceptQuoteRequest); (13)
          System.err.println(acceptQuote);
        }
      }
    }

1 | Prepare costs request
2 | Set validation only with total costs
3 | Limit is optional
4 | Quote reference can be empty
5 | Process costs calulation request
6 | Prepare quote request
7 | Process quote request
8 | Get entry for the quote
9 | Check quote
10 | Prepare accept quote request
11 | Set validation (Warning real execution)
12 | Set quote reference
13 | Process order execution

## Errors

Error code | Target | Description
--- | --- | ---
ACC_NOT_TRADING_ERR | Ordering | Process order with not trading account
ACC_NOT_VALID_ERR | Ordering | Process order with invalid account
ORD_ACTIVE_ERR | Ordering | Inactivate order in non pro version
ORD_AMOUNT_ERR | Ordering | Orders amount is not changable for selected order
ORD_DRIPPING_QUANTITY_ERR | Ordering | Dripping quantity error
ORD_COSTS_ERR | Ordering | Order costs information unavialable
ORD_COSTS_ABSENT_ERR | Ordering | Order costs information is not cached.
ORD_LIMIT_ERR | Ordering | Limit field is invalid
ORD_MODEL_ERR | Ordering | Order model is wrong
ORD_NOT_CANCELABLE_ERR | Ordering | Order is not cancelable
ORD_NOT_KNOWN_ERR | Ordering | Order is not known by the system
ORD_STOP_ERR | Ordering | Order stop is not changable
ORD_STOP_LIMIT_ERR | Ordering | Stop limit is not changable
ORD_TRALING_DISTANCE_ERR | Ordering | Traling distance is not changable
ORD_TRALING_LIMIT_TOLERANCE_ERR | Ordering | Traling limit tolerance is not changable
ORD_VALIDITY_DATE_ERR | Ordering | Validity date is not changable
ORD_WRONG_PRICE_TICKET_ERR | Ordering | Price ticket is not correct for this accept quote
ORD_QUOTE_ERR | Ordering | Quote is not valid
ORD_VALIDATION_ERR | Ordering | Selected validation can not be use for this request
ORD_COSTS_NOT_REQUESTED | Ordering | Costs are not requested before order or costs information is old
STK_NOT_FOUND_ERR | Stocks | Stock exchange is unknown
INTERNAL_ERR | System | Internal engine error
SYSTEM_ERR | System | GRPC error
UNSUPPORTED_OPERATION_ERR | System | Operation is not supported

## Objects and types description

### AcceptQuoteRequest

Accept quote request represents information about one order that should be placed on the short term market

Field | Type | Description
--- | --- | ---
access_token | string | Access token
account_number | string | Trading account number
security_with_stockexchange | SecurityWithStockExchange | Security code with stock exchange
order_type | OrderType | Order type. It should be relevant to the requested GetQuoteRequest
amount | double | Amount, It should be relevant to the requested GetQuoteRequest
limit | double | Limit
quote_reference | string | Quote reference from GetQuoteRequest
validation | Validation | Validation flag. If value is WITHOUT_VALIDATION then backend system sends order actions directly to the market. If value is VALIDATE_ONLY then backend system doesn’t send order actions to the market, but validate order parameters. If value is VALIDATE_WITH_TOTAL_COSTS then order will validated by backend system and request total costs for the order. If value is VALIDATE_WITH_DETAIL_COSTS then order will validated by backend system and request detail costs for the order.
risk_class_override | bool | Risk class override flag. If true then allowes override user risk class
target_market_override | bool | Target market override flag. If true then allowes override target market
tax_nontransparent_override | bool | Tax non trasparent override flag. If true then allowes override tax intransparesity
accept_additional_fees | bool | Accept additinal fees flag. If true then allowes accept non transparent fees

### AccessTokenRequest

Access token request contains an access token data

Field | Type | Description
--- | --- | ---
access_token | string | Access token

### ActivateOrderRequest

Activate order request represents information for activation of one inactive order pro only

Field | Type | Description
--- | --- | ---
access_token | string | Access token
account_number | string | Trading account number
order_number | string | Order number for that this changes should be accepted
validation | Validation | Validation flag. This request allowes only WITHOUT_VALIDATION and VALIDATE_ONLY values. If value is WITHOUT_VALIDATION then backend system sends order actions directly to the market. If value is VALIDATE_ONLY then backend system doesn’t send order actions to the market, but validate order parameters.

### AggregatedCosts

Aggregated costs contain an information about estimated costs for the selected order

Field | Type | Description
--- | --- | ---
in_costs_absolute | double | In costs for the order
in_costs_relative | double | Percentage part of the in costs
in_costs_currency | string | Currency for the in costs
out_costs_absolute | double | Out costs for the order
out_costs_relative | double | Percentage part of the out costs
out_costs_currency | string | Currency for the out costs
instrument_costs_absolute | double | Instrument costs for the order
instrument_costs_relative | double | Percentage part of the instrument costs
instrument_costs_currency | string | Currency for the instrument costs
service_costs_absolute | double | Service costs for the order
service_costs_relative | double | Percentage part of the service costs
service_costs_currency | string | Currency for the servcie costs
subsidy_costs_absolute | double | Subsidy costs for the order
subsidy_costs_relative | double | Percentage part of the subsidy costs
subsidy_costs_currency | string | Currency for the subsidy costs
foreign_currency_costs_absolute | double | Foreign currency costs for the order
foreign_currency_costs_relative | double | Percentage part of the foreign currency costs
foreign_currency_costs_currency | string | Currency for the foreign currency costs
performance_impact_absolute | double | Performance impact for the order
performance_impact_relative | double | Percentage part of the performance impact
performance_impact_currency | string | Currency for the performance impact
expected_amount | double | Expected amount estimated for the order
expected_amount_currency | string | Currency for the expected amount

### AddOrderRequest

Add order request represents order data for the long term markets

Field | Type | Description
--- | --- | ---
access_token | string | Access token
account_number | string | Trading account number which used for the execution
security_with_stockexchange | SecurityWithStockExchange | Security code with stock exchange
order_type | OrderType | Order type
amount | double | Amount of the securities
order_model | OrderModel | Order model
order_supplement | OrderSupplement | Order supplement
cash_quotation | CashQuotation | Cach quotation
validity_date | Date | Order validity date
limit | double | Limit value
stop | double | Stop value. This value can be used only together with StopMarket, StopLimit and OneCancelOter order models.
stop_limit | double | Stop limit used in the StopLimit and OneCancelOther order models
trailing_distance | double | Traling distance in traling notation units or empty value
trailing_notation | TrailingNotation | Trailing notation for the trailing orders
trailing_limit_tolerance | double | Trailing limit tolerance for the trailing orders
dripping_quantity | double | Dripping quantity pro only
position_id | string | Position id of the depot position. It used only for sale certainly securities from depot
validation | Validation | Validation flag. If value is WITHOUT_VALIDATION then backend system sends order actions directly to the market. If value is VALIDATE_ONLY then backend system doesn’t send order actions to the market, but validate order parameters. If value is VALIDATE_WITH_TOTAL_COSTS then order will validated by backend system and request total costs for the order. If value is VALIDATE_WITH_DETAIL_COSTS then order will validated by backend system and request detail costs for the order.
risk_class_override | bool | Risk class override flag. If true then allowes override user risk class
target_market_override | bool | Target market override flag. If true then allowes override target market
tax_nontransparent_override | bool | Tax non trasparent override flag. If true then allowes override tax intransparesity
accept_additional_fees | bool | Accept additinal fees flag. If true then allowes accept non transparent fees
closed_realestate_fond_override | bool | Closed realestate fond override. If true then allowes sell fonds over fds
inactive | bool | Inactive order flag, pro only. If true then order market as inactive and don’t routed to the marker. To activate order please use ActivateOrder function

### CancelOrderRequest

Cancel order request represents canceling information for one order on the market or one inactive order

Field | Type | Description
--- | --- | ---
access_token | string | Access token
account_number | string | Trading account number
order_number | string | Order number for that this changes should be accepted
validation | Validation | Validation flag. This request allowes only WITHOUT_VALIDATION value. If value is WITHOUT_VALIDATION then backend system sends order actions directly to the market. Otherwise request will fail.

### CashQuotation

Cash quotation is additional parameter of the order

Field | Description
--- | ---
NOTHING | Quotation is not defined
KASSA | Kassa quotation
AUCTION | Auction quotation
OPENING | Opening quotation
INTRADAY | Intraday quotation
CLOSING | Close quotation

### CategoryCost

Represents one category cost.

Field | Type | Description
--- | --- | ---
category_id | string | Category id
category_label | string | Human redable category label
total_sum_absolute | double | Total absolute sum of the children values
total_sum_relative | double | Total relative sum of the children values
currency | string | Currency for absolute sum
detail_costs | List of DetailCost | List of child values or detailed information.

### ChangeOrderRequest

Change order request contains parameters for the order change. Be careful: not all combinations are possible.

Field | Type | Description
--- | --- | ---
access_token | string | Access token
account_number | string | Trading account number
order_number | string | Order number for that this changes should be accepted
limit | double | New limit, shouldn’t filled for market order
stop | double | New stop value
stop_limit | double | New stop limit value
amount | double | New amount
validity_date | Date | New validity date
order_model | OrderModel | New order model
order_supplement | OrderSupplement | New order supplement
dripping_quantity | double | Dripping quantity pro only
validation | Validation | Validation flag. This request allowes only WITHOUT_VALIDATION and VALIDATE_ONLY values. If value is WITHOUT_VALIDATION then backend system sends order actions directly to the market. If value is VALIDATE_ONLY then backend system doesn’t send order actions to the market, but validate order parameters.
trailing_distance | double | New trailing distance
trailing_limit_tolerance | double | New traling limit tolerance

### CurrencyRateReply

Returns currency rate

Field | Type | Description
--- | --- | ---
currency_from | string | Source currency
currency_to | string | Target currency
currency_rate | double | Currency rate
error | Error | Error information if occuirs

### CurrencyRateRequest

CurrencyRateRequest used for the determination of the currency rate from one currency rate to second currency. Results depends from user market data aboniment and can be realtime or delayed.

Field | Type | Description
--- | --- | ---
access_token | string | Access token
currency_from | string | Source currency
currency_to | string | Target currency

### Date

Represents a whole calendar date, e.g. date of birth. The time of day and time zone are either specified elsewhere or are not significant. The date is relative to the Proleptic Gregorian Calendar. The day may be 0 to represent a year and month where the day is not significant, e.g. credit card expiration date. The year may be 0 to represent a month and day independent of year, e.g. anniversary date. Related types are [google.type.TimeOfDay][google.type.TimeOfDay] and `google.protobuf.Timestamp`.

Field | Type | Description
--- | --- | ---
year | int32 | Year of date. Must be from 1 to 9999, or 0 if specifying a date without a year.
month | int32 | Month of year. Must be from 1 to 12.
day | int32 | Day of month. Must be from 1 to 31 and valid for the year and month, or 0 if specifying a year/month where the day is not significant.

### DeactivateOrderRequest

Deactivate order request represents information for deactivation of one active order pro only

Field | Type | Description
--- | --- | ---
access_token | string | Access token
account_number | string | Trading account number
order_number | string | Order number for that this changes should be accepted
validation | Validation | Validation flag. This request allowes only WITHOUT_VALIDATION and VALIDATE_ONLY values. If value is WITHOUT_VALIDATION then backend system sends order actions directly to the market. If value is VALIDATE_ONLY then backend system doesn’t send order actions to the market, but validate order parameters

### DepotEntries

Field | Type | Description
--- | --- | ---
account | TradingAccount | Trading account
entries | List of DepotEntry | Depot entries list
error | Error | Error information if occuirs

### DepotEntry

Depot entry contains information about one security in the depot. This entry combines data from one or more depot positions

Field | Type | Description
--- | --- | ---
security_code | SecurityCode | Security code
positions | List of DepotPosition | List of linked depot positions. This list contains at least one element
effective_amount | double | Effective amount
scheduled_amount | double | Scheduled amount
total_amount | double | Total amount of the securities
sell_possible | bool | True if sell possible for this entry or false otherwise. This value can be true only if all child positions have sell_possible = true
unit_note | UnitNote | Unit note
blocked | bool | True if entry is blocked or false otherwise
purchase_quotation | double | Purchase quotation or NaN if not defined
purchase_currency | string | Purchase currency or empty value if not defined
purchase_currency_rate | double | Purchase currency rate or NaN if not defined
open_sales | double | Open sales

### DepotPosition

Depot posiotion contains information about one position in the depot

Field | Type | Description
--- | --- | ---
amount | double | Ammount of the securities
position_id | string | Position identification
sell_possible | bool | True if sell of the position is possible or false otherwise
unit_note | UnitNote | Unit note
blocked | bool | True if entry is blocked or false otherwise
purchase_quotation | double | Purchase quotation or NaN if not defined. Currently this field ALWAYS undefined, reserved for future use
purchase_currency | string | Purchase currency or empty value if not defined
purchase_currency_rate | double | Purchase currency rate or NaN if not defined

### DetailCost

Detail cost contains one entry for the selected category

Field | Type | Description
--- | --- | ---
detail_id | string | Detail id
detail_label | string | Human redable detail label
value_absolute | double | Absolute value for this entry
value_relative | double | Relative value for this entry
currency | string | Currency for this entry
detail_type | string | Specific entry type

### Empty

Empty represents absent parameter or result

Field | Type | Description
--- | --- | ---

### Error

Error object

Field | Type | Description
--- | --- | ---
code | string | Error code
message | string | Error message

### LimitToken

Limit token represents a possibility to trade on the short term markets (AcceptQuote) and long term markets (AddOrder)

Field | Description
--- | ---
LIMIT_AND_QUOTE | AcceptQuote and AddOrder possible
QUOTE_ONLY | AcceptQuote only possible
LIMIT_ONLY | AddOrder only possible

### LoginReply

Login reply provides information that need for the access to the TAPI

Field | Type | Description
--- | --- | ---
access_token | string | Access token is used in each request by the access to the TAPI.
error | Error | Error information if occuirs

### LoginRequest

Login request provides data for initial access to the TAPI

Field | Type | Description
--- | --- | ---
secret | string | Secret is user defined access string. It’s not possible to restore this secret directly. See double MD5 hash logic + salt

### LogoutReply

Field | Type | Description
--- | --- | ---
error | Error | Error information if occuirs

### LogoutRequest

Field | Type | Description
--- | --- | ---
access_token | string | Access token to invalidate.

### Order

Order represent one order object

Field | Type | Description
--- | --- | ---
security_with_stockexchange | SecurityWithStockExchange | Security with stock echange
order_type | OrderType | Order type
order_number | string | Order number
amount | double | Amount of the securities
order_model | OrderModel | Order model
order_supplement | OrderSupplement | Order supplement
cash_quotation | CashQuotation | Cache quotation
executed_amount | double | Executed amount
order_status | OrderStatus | Order status
status_timestamp | Timestamp | Date and time of the order status
validity_date | Date | Validity date of the order
limit | double | Limit value. Used as the order limit for all Limit order model with exception of the StopLimit order model. For this order model please use stop limit field.
stop | double | Stop value. This value can be used only together with StopMarket, StopLimit and OneCancelOter order models.
stop_limit | double | Stop limit value Can be used only tigether with the StopLimit order model. The meaning of the value is limit of the order after stop.
trailing_distance | double | Traling distance in traling notation units or empty value
trailing_notation | TrailingNotation | Trailing notation for the trailing orders
trailing_limit_tolerance | double | Trailing limit tolerance for the trailing orders
dripping_quantity | double | Dripping quantity pro only
trading_partner_name | string | Trading partner name
execution_quote | double | Execution quote for the executed amount
unique_id | string | Unique id of the order. Used for the order matching. In the pro version of the ActiveTrader order_number can be changed after activation / deactivation. All order activities need actual or delivered form the system order_number. Typical scenario is to map and update unique id to the order number delivered from the API.

### OrderBookEntry

Orderbook entry contains data about one level of the order book. This is bid price, ask price, bid volume, ask volume. Entries with lower index have lower ask and higer bid prices.

Field | Type | Description
--- | --- | ---
bid_price | double | Bid price
ask_price | double | Ask price
bid_volume | double | Bid volume
ask_volume | double | Ask volume

### OrderCosts

Order costs represents information about order action estimated costs. This information is only estimated values and is depended from real execution quotes, time, etc.

Field | Type | Description
--- | --- | ---
estimated_total_costs | double | Estimated total cost for order action
cost_id | string | Reference backend cost id
categorie_costs | List of CategoryCost | List of the cost categories. Filled only by validation request with detailed information.
aggregated_costs | AggregatedCosts | Aggregated costs for the order. Filled only by validation request with validation information.

### OrderModel

Order model represents possible orders

Field | Description
--- | ---
NO_ORDER_MODEL | Order model absent
MARKET | Market order
LIMIT | Limit order
STOP_MARKET | Stop market order.
STOP_LIMIT | Stop limit order
ONE_CANCELS_OTHER_MARKET | One cancels other market order
ONE_CANCELS_OTHER_LIMIT | One cancels other limit order
TRAILING_STOP_MARKET | Trailing stop market order
TRAILING_STOP_LIMIT | Trailing stop limit order

### OrderReply

Order reply represents result of the add order or accept quote requests

Field | Type | Description
--- | --- | ---
account | TradingAccount | Trading account
order | Order | Result order
order_costs | OrderCosts | Order costs. This field contains data if order costs are requested
error | Error | Error information if occuirs

### Orders

Orders represent pushed information about orders from one trading accounts

Field | Type | Description
--- | --- | ---
account | TradingAccount | Trading account
orders | List of Order | List of the orders
error | Error | Error information if occuirs

### OrderStatus

Order status represents status of the order

Field | Description
--- | ---
NO_ORDER_STATUS | Status is not defined
NEW | New order
OPEN | Open order
EXECUTED | Fully executed order
PARTIALLY_EXECUTED | Partially executed order
CANCELED | Canceled order
CANCELED_FORCED | Canceled forced order
CANCELED_NOTED | Canceling noted order
CANCELED_TIMEOUT | Canceling timeout order
CHANGED | Changed order
CHANGED_NOTED | Changing noted order
INACTIVE | Inactive order pro only
INACTIVE_NOTED | Inactivation noted order pro only
STORNO | Storno order

### OrderSupplement

Order supplement is additional parameter by order definition

Field | Description
--- | ---
NORMAL | Normal order supplement
IMMIDIATE_OR_CANCEL | Immidiate or cancel order supplement
FILL_OR_KILL | Fill or kill order supplement
ICEBERG | Icesberg order supplement. Allowes to delivery amount in portions. pro only
MARKET_PRICE | Market place order supplement

### OrderType

Order type represents different buy / sell order possibilities

Field | Description
--- | ---
NO_ORDER_TYPE | Order type is not defined
BUY | Buy order type
SELL | Sell order type
SHORT_SELL | Short sell order type
SHORT_COVER | Short cover order type. This type is not allowed as input parameter
FORCED_COVER | Rorced cover order type. This type is not allowed as input parameter

### PriceEntry

Field | Type | Description
--- | --- | ---
open_price | double | Open price
close_price | double | Close price
high_price | double | High price
low_price | double | Low price
volume | double | Volume, can not be filled
open_time | Timestamp | Open time
close_time | Timestamp | Close time

### QuoteEntry

Quote entry represents one answer with quote information from one stock exchange This reply contains both buy and sell price. The quote reference can be used only with requested order type. Second value is present only for information goals.

    order type: BUY ->  quote reference for buy price and reference,
                        sell price and reference are informative only
    order type: SELL -> quote reference for sell price and reference,
                        buy price and reference are informative only

Field | Type | Description
--- | --- | ---
stock_exchange | StockExchange | Stock exchange where infomation was requested
buy_price | double | Buy price
buy_volume | double | Buy volume
sell_price | double | Sell price
sell_volume | double | Sell volume
last_price | double | Last price
last_volume | double | Last volume
last_time | Timestamp | Date and time of the last price
currency | string | Currency
quote_reference | string | Quote reference. Used for the accept quite request. Can be empty if accept quote is not possible.
order_type | OrderType | Used by call order type
error | Error | Error information if occuirs

### QuoteReply

Quote reply represents data with quote answers from requested markets

Field | Type | Description
--- | --- | ---
security_code | SecurityCode | Security code
order_type | OrderType | Order type
price_entries | List of QuoteEntry | List of the quites
error | Error | Error information if occuirs

### QuoteRequest

Quote request represents data to get information about actual quotes on the selected makets

Field | Type | Description
--- | --- | ---
access_token | string | Access token
security_code | SecurityCode | Security code
order_type | OrderType | Order type. Only BUY or SELL are allowed
amount | double | Amount of securities. Relevant to the short term markets
stock_exchanges | List of StockExchange | List of stock exchanges

### SecurityChangedField

SecurityChangedField represents information about changed fields during marked data event. Not all field can be initialized. There are only changed fields. Some fields can be changed, but have undefined state for example NaN.

Field | Description
--- | ---
NONE | No data
LAST_PRICE | Price of the last trade
LAST_VOLUME | Volume last trade
LAST_DATE_TIME | Last quote date and time
TODAY_NUM_TRADES | Today number of tradings
TODAY_VOLUME | Today volume
ASK_PRICE | Last ask price
ASK_VOLUME | Volume last ask
ASK_TIME | Time of the last ask
BID_PRICE | Last bid price
BID_VOLUME | Volume last bid
BID_TIME | Time of the last bid
PREVIOUS_PRICE | Quote of the previous trading day
PREVIOUS_DATE | Date of the previous trading day
RELATIVE_DIFF | Relative difference to the previous day
ABS_DIFF | Absolute difference to the previous day
HIGH_PRICE | Highest price
LOW_PRICE | Lowest price
OPEN_PRICE | Price at opening
WEEK_HIGH_PRICE | Highest price of the previous week
DATE_WEEK_HIGH | Date of highest price of the previous week
WEEK_LOW_PRICE | Lowest price of the previous week
DATE_WEEK_LOW | Date of lowest price of the previous week
MONTH_HIGH_PRICE | Highest price of the previous month
DATE_MONTH_HIGH | Date of highest price of the previous month
MONTH_LOW_PRICE | Lowest price of the previous month
DATE_MONTH_LOW | Date of lowest price of the previous month
YEAR_HIGH_PRICE | Highest price of the current year
DATE_YEAR_HIGH | Date of the highest price of the current year
YEAR_LOW_PRICE | Lowest price of the current year
DATE_YEAR_LOW | Date of the lowest price of the current year
LAST_ADDENDUM | Addendum of the last price.
TRADING_PHASE | Trading phase
INDICATIVE_PRICE | Indicative price
PREVALENCE_VOLUME | Trading volume corresponding to the last price

### SecurityClass

Represents information about security class

Field | Description
--- | ---
NO_SECURITY_CLASS | Security class is undefined on unknown
STOCK | Stock security class
BOND | Bond security class
CERTIFICATE | Certificate security class
PRECIOUS_METAL | Precious metal security class
PARTICIPATION_CERTIFICATE | Participation certificate security class
FUNDS | Funds security class
MUTUAL_FUNDS | Mutual funds security class
WARRANT | Warrants security class
FUTURE | Futures security class
INDEX | Indexies security class
OTHERS | Other securities security class
FUTURE_C1 | Future c1 security class
FUTURE_C2 | Future c2 security class
FUTURE_C3 | Future c3 security class
TRACKERS | Trackers security class
CURRENCY | Currency security class
COMMODITY | Commodity security class

### SecurityCode

Field | Type | Description
--- | --- | ---
code | string | Security code
code_type | SecurityCodeType | Security code type (WKN, ISIN, etc)

### SecurityCodeType

Represents information about security code type Some of the types are refer to the market data provider (FactSet)

Field | Description
--- | ---
NO_CODE_TYPE | Unknown code type
WKN | WKN code type
ISIN | ISIN code type
ID_NOTATION | Factset id notation
ID_OSI | Factset id osi
ID_INSTRUMENT | Factset id instrument
MNEMONIC | Mnemonic or symbol
MNEMONIC_US | US Mnemonic or symbol

### SecurityInfoReply

Returns security information

Field | Type | Description
--- | --- | ---
name | string | Security name
security_class | SecurityClass | Security class
security_codes | List of SecurityCode | Security codes with security type (WKN, ISIN, etc)
stock_exchange_infos | List of SecurityStockExchangeInfo | Stockexchange info (stock exchange, name)
unit_note | UnitNote | Unit note
error | Error | Error information if occuirs

### SecurityInfoRequest

Requests security information for security code

Field | Type | Description
--- | --- | ---
access_token | string | Access token
security_code | SecurityCode | Security code with security type (WKN, ISIN)

### SecurityMarketDataReply

Returns market data information

Field | Type | Description
--- | --- | ---
security_with_stockexchange | SecurityWithStockExchange | Security with stockExchange object (security code, stock exchange)
changed_fields | List of SecurityChangedField | Security fields, which were changed
currency | string | Currency
last_price | double | Fields Price of the last trade
last_volume | double | Volume last trade
last_date_time | Timestamp | Last quote date and time
today_num_trades | int32 | Today number of tradings
today_volume | double | Today volume
ask_price | double | Last ask price
ask_volume | double | Volume last ask
ask_time | Timestamp | Time of the last ask
bid_price | double | Last bid price
bid_volume | double | Volume last bid
bid_time | Timestamp | Time of the last bid
previous_price | double | Quote of the previous trading day
previous_date | Date | Date of the previous trading day
relative_diff | double | Relative difference to the previous day
abs_diff | double | Absolute difference to the previous day
high_price | double | Highest price
low_price | double | Lowest price
open_price | double | Price at opening
week_high_price | double | Highest price of the previous week
date_week_high | Date | Date of highest price of the previous week
week_low_price | double | Lowest price of the previous week
date_week_low | Date | Date of lowest price of the previous week
month_high_price | double | Highest price of the previous month
date_month_high | Date | Date of highest price of the previous month
month_low_price | double | Lowest price of the previous month
date_month_low | Date | Date of lowest price of the previous month
year_high_price | double | Highest price of the current year
date_year_high | Date | Date of the highest price of the current year
year_low_price | double | Lowest price of the current year
date_year_low | Date | Date of the lowest price of the current year
last_addendum | string | Addendum of the last price.
trading_phase | TradingPhase | Trading phase
indicative_price | double | Indicative price
prevalence_volume | double | Trading volume corresponding to the last price
error | Error | Error information if occuirs

### SecurityMarketDataRequest

Requests market data values for defined security with stockexchange

Field | Type | Description
--- | --- | ---
access_token | string | Access token
security_with_stockexchange | SecurityWithStockExchange | Security with stockExchange object (security code, stock exchange)
currency | string | Currency

### SecurityOrderBookReply

SecurityOrderBookReply represents information with orderbook market data. Currently this information is avialable for the Xetra stock exchange for the accepted for the second level market data instruments

Field | Type | Description
--- | --- | ---
security_with_stockexchange | SecurityWithStockExchange | Security with stock exchange object (security code, stock exchange)
currency | string | Currency of the order book entries
order_book_entries | List of OrderBookEntry | List of the order book entries
error | Error | Error information if occuirs

### SecurityOrderBookRequest

Requests orderbook data for security with stockexchange

Field | Type | Description
--- | --- | ---
access_token | string | Access token
security_with_stockexchange | SecurityWithStockExchange | Security with stockExchange object (security code, stock exchange)
currency | string | Requested currency. If not filled used default currency. Otherwise values will be converted to requested currency.

### SecurityPriceHistoryReply

Returns history data for defined security

Field | Type | Description
--- | --- | ---
security_with_stockexchange | SecurityWithStockExchange | Security with stockExchange object (security code, stock exchange)
currency | string | Currency
price_entries | List of PriceEntry | List of the price entries
error | Error | Error information if occuirs

### SecurityPriceHistoryRequest

Requests history data for one security on one stockexchange in intraday or historical format

Field | Type | Description
--- | --- | ---
access_token | string | Access token
security_with_stockexchange | SecurityWithStockExchange | Security with stockExchange object (security code, stock exchange)
days | int32 | Amount of the day in the past. This value should be positive. Maximal value for the intraday resolution is 15.
time_resolution | TimeResolution | Time resolution for the data

### SecurityStockExchangeInfo

Security stock exchange info represents trading information about one security on the one market

Field | Type | Description
--- | --- | ---
stock_exchange | StockExchange | Stockexchange (id und issuer)
buy_limit_token | LimitToken | Possible limit token for buy orders
sell_limit_token | LimitToken | Possible limit token for sell orders
buy_trading_types | List of TradingPossibility | Buy trading data (order models, order supplements, trailing notations)
sell_trading_types | List of TradingPossibility | Sell trading data (order models, order supplements, trailing notations)
maximal_order_date | Date | Maximal order validity date
short_mode | ShortMode | Short selling mode

### SecurityWithStockExchange

Field | Type | Description
--- | --- | ---
security_code | SecurityCode | Security code object
stock_exchange | StockExchange | Stock exchange object

Table 6. AccessService
Function | Description
--- | ---
LoginReply = Login(LoginRequest) | Validates client by the TAPI and gets access data
LogoutReply = Logout(LogoutRequest) | Invalidates client by the TAPI and gets logout result

Table 7. AccountService
Function | Description
--- | ---
TradingAccounts = GetTradingAccounts(AccessTokenRequest) | Gets trading accounts @return TradingAccounts List of trading accounts
TradingAccountInformation ⇐ StreamTradingAccount(TradingAccountRequest) | Subscribes one trading account for updates @param TradingAccount Trading account for push @stream TradingAccountInformation Specific information for subscribed account (balance, kredit line, etc.)
TradingAccountTransactions ⇐ StreamTradingAccountTransactions(TradingAccountRequest) | Subscribes one trading account for the transactions updates @param TradingAccount Trading account for push @stream TradingAccountInformation Transactions list for subscribed account

Table 8. DepotService
Function | Description
--- | ---
DepotEntries ⇐ StreamDepot(TradingAccountRequest) | Subscribes one trading account for the depot data updates @param TradingAccount Trading account for push @stream DepotEntries depot entries linked to the account
Empty = UpdateDepot(TradingAccountRequest) | Initiates depot update action. All changes come by the StreamDepot subscription. This function doesn’t wait for the action result. @param TradingAccount Trading account for update

Table 9. OrderService
Function | Description
--- | ---
Orders ⇐ StreamOrders(TradingAccountRequest) | Subscribes one trading account for orders updates @param TradingAccount Trading account for push @stream Orders Orders list for seleted account
Empty = UpdateOrders(TradingAccountRequest) | Initiates orders update action. All changes come by the StreamOrders subscription. This function doesn’t wait for the action result. @param TradingAccount Trading account for update
QuoteReply = GetQuote(QuoteRequest) | Request market quote for the selected security on the selected stock exchanges. @param QuoteRequest quote request with interested security and stock exchanges @return QuoteReply quote reply with quotes
OrderReply = AcceptQuote(AcceptQuoteRequest) | Sends accept quote order request to the short term market @param AcceptQuoteRequest accept quote request with order parameters @return OrderReply result order or error
OrderReply = AddOrder(AddOrderRequest) | Sends long term order to the market @param AddOrderRequest order request with order parameters @return OrderReply result order or error
OrderReply = ChangeOrder(ChangeOrderRequest) | Sends order change request to the market @param ChangeOrderRequest changed order request with order parameters @return OrderReply result order or error
OrderReply = CancelOrder(CancelOrderRequest) | Sends order cancel request to the market @param CancelOrderRequest cancel order request with order reference @return OrderReply result order or error
OrderReply = ActivateOrder(ActivateOrderRequest) | Sends order activate request to the market. pro only @param ActivateOrderRequest activate order request with order parameters @return OrderReply result order or error
OrderReply = DeactivateOrder(DeactivateOrderRequest) | Sends order deactivate request to the market. pro only @param DeactivateOrderRequest deactivate order request with order parameters @return OrderReply result order or error

Table 10. SecurityService
Function | Description
--- | ---
SecurityInfoReply = GetSecurityInfo(SecurityInfoRequest) | Gets security information about security @param SecurityInfoRequest Request object with interested security @return SecurityInfoReply Complete information about security
SecurityMarketDataReply ⇐ StreamMarketData(SecurityMarketDataRequest) | Subscribes security with stock exchange for market data updates @param SecurityMarketDataRequest Market data request with interested security and stock exchange @stream SecurityMarketDataReply Reply with all market data values
SecurityOrderBookReply ⇐ StreamOrderBook(SecurityOrderBookRequest) | Subscribes security with stock exchange for orderbook updates @param SecurityOrderBookRequest Orderbook data request with interested security and stock exchange @stream SecurityOrderBookReply Reply with all orderbook values
CurrencyRateReply ⇐ StreamCurrencyRate(CurrencyRateRequest) | Subscribes for currency rate from one currency to another currency. @param SecurityOrderBookRequest currency rate request with interested currencies from/to @stream CurrencyRateReply reply with currency rate
SecurityPriceHistoryReply = GetSecurityPriceHistory(SecurityPriceHistoryRequest) | Requests history data for one security on one stockexchange in intraday or historical format @param SecurityPriceHistoryRequest Data with security, stockexchange, how many days and resolution @return SecurityPriceHistoryReply List of the historical quotes or an error

Table 11. StockExchangeService
Function | Description
--- | ---
StockExchangeDescriptions = GetStockExchanges(AccessTokenRequest) | Gets predefined stockexchages @return StockExchangeDescriptions list of stock exchange informations
StockExchangeDescription = GetStockExchange(StockExchangeRequest) | Gets specific stock exchange @param StockExchange Requested stock exchange @return StockExchangeDescription Stock exchange information

### ShortMode

Short mode gives information amout security shortability on the selected market.

Field | Description
--- | ---
NO_SHORT_MODE | Undefined short selling
YES | Short selling is possible
NO | No short selling
TEMPORARY_NO | Temporary no short selling
INTRADAY | Intraday short selling
OVERNIGHT | Overnight short selling
INTRADAY_AND_OVERNIGHT | Intraday and Overnight short selling

### StockExchange

Stock exchange data

Field | Type | Description
--- | --- | ---
id | string | Stock exchange id
issuer | string | Stock exchange issuer. Can be null

### StockExchangeDescription

Field | Type | Description
--- | --- | ---
stock_exchange_info | StockExchangeInfo | Stock exchange information
error | Error | Error information if occuirs

### StockExchangeDescriptions

Field | Type | Description
--- | --- | ---
stock_exchange_infos | List of StockExchangeInfo | List with stock exchange information
error | Error | Error

### StockExchangeInfo

Field | Type | Description
--- | --- | ---
stockExchange | StockExchange | Stock exchange object
name | string | Stock exchange name

### StockExchangeRequest

Stock exchange request contains data that need to request stock exchange related data

Field | Type | Description
--- | --- | ---
access_token | string | Access token
stock_exchange | StockExchange | Stock exchange

### TimeResolution

Time resolution represents information about price aggregation

Field | Description
--- | ---
NO_RESOLUTION | Undefined resolution
TICK | Tick resolution. intraday. Be careful, in same cases there is a lot of data.
SECOND | Second resolution intraday
MINUTE | Minute resolution intraday
HOUR | Hour resolution intraday
DAY | Day resolution historic

### Timestamp

A Timestamp represents a point in time independent of any time zone or calendar, represented as seconds and fractions of seconds at nanosecond resolution in UTC Epoch time. It is encoded using the Proleptic Gregorian Calendar which extends the Gregorian calendar backwards to year one. It is encoded assuming all minutes are 60 seconds long, i.e. leap seconds are "smeared" so that no leap second table is needed for interpretation. Range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By restricting to that range, we ensure that we can convert to and from RFC 3339 date strings. See https://www.ietf.org/rfc/rfc3339.txt.

Examples

Example 1: Compute Timestamp from POSIX `time()`.

    Timestamp timestamp;
    timestamp.set_seconds(time(NULL));
    timestamp.set_nanos(0);

Example 2: Compute Timestamp from POSIX `gettimeofday()`.

    struct timeval tv;
    gettimeofday(&tv, NULL);

    Timestamp timestamp;
    timestamp.set_seconds(tv.tv_sec);
    timestamp.set_nanos(tv.tv_usec * 1000);

Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`.

    FILETIME ft;
    GetSystemTimeAsFileTime(&ft);
    UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;

    // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
    // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
    Timestamp timestamp;
    timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
    timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));

Example 4: Compute Timestamp from Java `System.currentTimeMillis()`.

    long millis = System.currentTimeMillis();

    Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
        .setNanos((int) ((millis % 1000) * 1000000)).build();

Example 5: Compute Timestamp from current time in Python.

    timestamp = Timestamp()
    timestamp.GetCurrentTime()

JSON Mapping

In JSON format, the Timestamp type is encoded as a string in the RFC 3339 format. That is, the format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z" where {year} is always expressed using four digits while {month}, {day}, {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution), are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone is required. A proto3 JSON serializer should always use UTC (as indicated by "Z") when printing the Timestamp type and a proto3 JSON parser should be able to accept both UTC and other timezones (as indicated by an offset).

For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past 01:30 UTC on January 15, 2017.

In JavaScript, one can convert a Date object to this format using the standard toISOString() method. In Python, a standard `datetime.datetime` object can be converted to this format using `strftime` with the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use the Joda Time’s `ISODateTimeFormat.dateTime()` to obtain a formatter capable of generating timestamps in this format.

Timestamp represents date + time format

Field | Type | Description
--- | --- | ---
seconds | int64 | Represents seconds of UTC time since Unix epoch 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z inclusive.
nanos | int32 | Non-negative fractions of a second at nanosecond resolution. Negative second values with fractions must still have non-negative nanos values that count forward in time. Must be from 0 to 999,999,999 inclusive.

### TradingAccount

TradingAccount is trading account connected to the depot

Field | Type | Description
--- | --- | ---
account_number | string | Account number
depot_number | string | Depot number
name | string | Name of the account owners
tradable | bool | If account is tradable then true or false otherwise

### TradingAccountInformation

TradingAccountInformation contains specific for this account information

Field | Type | Description
--- | --- | ---
account | TradingAccount | Trading account
balance | double | Account balance
credit_limit | double | Credit limit information
buying_power | double | Buying power
credit_limit_intraday | double | Credit limit intraday information, pro only
buying_power_intraday | double | Buyng power intraday, pro only
error | Error | Error information if occuirs

### TradingAccountRequest

Trading account request contains trading account related data

Field | Type | Description
--- | --- | ---
access_token | string | Access token
trading_account | TradingAccount | Trading account

### TradingAccounts

TradingAccounts contains account information from current session

Field | Type | Description
--- | --- | ---
accounts | List of TradingAccount | List of trading accounts
error | Error | Error information if occuirs

### TradingAccountTransactions

TradingAccountTransactions contains account transactions

Field | Type | Description
--- | --- | ---
account | TradingAccount | Trading account
transactions | List of Transaction | List of transactions
error | Error | Error information if happened

### TradingPhase

Represents stock exchange trading phase. Some values are refer to the Xetra stock exchange

Field | Description
--- | ---
NONE | Unknown trading phase
PRETRADE | Pretrade trading phase
POSTTRADE | Posttrade trading phase
START | Start trading phase
END | End trading phase
VOLA | Vola trading phase
OCALL | OCall trading phase
ICALL | ICall trading phase
CCALL | CCall trading phase
TRADE | Trade trading phase
TRADE_INDICATIVE | Trade indicative trading phase
TRADE_BEST_BID_ASK | Trade best bid / ask trading phase
TRADE_AUCTION_NO_INDICATIVE | Trade auction, but not indicative trading phase

### TradingPossibility

Trading possibility represents allowed variants to trade on specific stock exchange. Each trading possibility is a combination of the parameters. The list of the order possibilites is all possible combinations:

    MARKET;NORMAL;ABSOLUTE;{KASSA;AUCTION}
    LIMIT;NORMAL;ABSOLUTE;{KASSA;AUCTION}
    MARKET;NORMAL;RELATIVE;{KASSA;AUCTION}
    LIMIT;NORMAL;RELATIVE;{KASSA;AUCTION}
    ...

Field | Type | Description
--- | --- | ---
order_model | OrderModel | Order model
order_supplement | OrderSupplement | Order supplement
trailing_notation | TrailingNotation | Trailing notation
cash_quotations | List of CashQuotation | List of allowed cash_quatations

### TradingState

Trading state represents information about tradability. Security can be tradable or not (ex. index)

Field | Description
--- | ---
NO_TRADING_STATE | Trading state is not defined
TRADABLE | Tradable state
NOT_TRADABLE | Not tradable state

### TrailingNotation

Trailing notation represent notation type by trailing orders

Field | Description
--- | ---
NO_TRAILING_NOTATION | Trailing notation is not defined
ABSOLUTE | Absolute order notation
RELATIVE | Relative order notation

### Transaction

Transaction contains onformation about one transaction

Field | Type | Description
--- | --- | ---
transaction_date | Date | Transaction date
amount | double | Amount value
opponent | string | Transaction opponent
information | string | Information about transaction
value_date | Date | Value date

### UnitNote

Unit node type

Field | Description
--- | ---
NO_UNIT_NOTE | Unit note is not defined
PIECE | Piece unit note
PERCENT | Percent unit node. Pieces = Percent/100
PERMIL | Permile unit node. Pieces = Percent/1000
POINTS | Points unit node
MISK | Misk unit node

### Validation

Validation type for the order actions

Field | Description
--- | ---
WITHOUT_VALIDATION | Order action will routed directly to the market.
VALIDATE_ONLY | Order will checked by the backend system, but not will be routed to market
VALIDATE_WITH_TOTAL_COSTS | Order will checked by the backend system, but not will be routed to market. Additionally will be requested estimated order action total costs.
VALIDATE_WITH_DETAIL_COSTS | Order will checked by the backend system, but not will be routed to market. Additionally will be requested estimated order action detail costs.
TOTAL_COSTS_ONLY | For the order will be requested estimated order action total costs. No backend system validation is processed.

## Questions and Answers

1. Why is used GRPC engine?

   The GRPC is fastest engine for push and pull messaging with building security support. It allowes to reduce time for requests execution (ex. add order) and cares about low level communication.

2. Is will be supported another languages?

   We delivery original protobuf protocol description. It can be used for the code generation for other programming languages like C++, Python, Go, Ruby, Node.js, Android Java, Objective-C, PHP, Dart and Web. For more information please refer to the grpc.io

3. Is it planned to extend TAPI?

   If we see an interest from the customers to use additional functionality, then TAPI can be extended.

4. Where I can ask questions / get additional information about TAPI?

   Please use next link or refer to the support team.