Flutter金融投资插件tinkoff_invest的使用

Flutter金融投资插件tinkoff_invest的使用

tinkoff_invest

pub package Dart

此项目是使用Dart语言实现的工具包,用于与Tinkoff Investments OpenAPI交互,可以用来创建交易机器人。

开始工作

要使用该插件,请在你的pubspec.yaml文件中添加tinkoff_invest作为依赖项。

获取认证令牌

您可以在您的Tinkoff个人账户的投资部分获取认证令牌。具体步骤如下:

  1. 转到设置。
  2. 确认“交易确认码”功能已关闭。
  3. 为交易和沙盒模式生成一个令牌。
  4. 复制并保存令牌,因为之后无法查看它,尽管您可以生成无限数量的令牌。

文档

可以直接通过此链接找到OpenAPI的文档。

快速开始

为了与OpenAPI进行交互,需要创建一个TinkoffInvestApi实例:

const token = 'your_token';
final api = TinkoffInvestApi(token);

// 请求当前的资产组合
final portfolioRes = await api.portfolio.load();
if (portfolioRes.isValue) {
  final portfolio = portfolioRes.asValue!.value.payload;
  print('Portfolio: ${portfolio.positions}');
} else {
  print('Load portfolio failed: ${portfolioRes.asError!.error}');
}

每个API请求都会返回一个Result对象,表示结果是成功还是错误。可以通过res.isValue属性检查是否成功。如果成功,可以使用res.asValue!.value访问结果。如果失败,则可以使用res.asError!.error获取错误信息。这可能是一个ErrorResponse实例,但不一定如此。

SDK的使用示例(包括沙盒模式)可以在以下目录中找到:example


示例代码

// 忽略打印
import 'package:tinkoff_invest/tinkoff_invest.dart';

Future<void> main() async {
  const token = 'your_token';

  // 在沙盒模式下运行
  const sandboxMode = true;
  // 可以启用调试模式,以便所有请求都打印到控制台
  const debug = false;

  // 创建API实例
  final api = TinkoffInvestApi(token, sandboxMode: sandboxMode, debug: debug);

  // 仅适用于沙盒模式
  // 配置沙盒账户
  await api.sandbox.register(); // 创建配置文件
  await api.sandbox.currenciesBalance(Currency.USD, 1000); // $1000存入账户
  // --

  // 请求当前的货币余额
  final res = await api.portfolio.currencies();
  if (res.isValue) {
    final response = res.asValue!.value;
    final data = response.payload;

    print('Currencies: ${data.currencies}');
    // 输出:
    // Currencies: [
    //   CurrencyPosition(currency: Currency.EUR, balance: 0.0, blocked: null),
    //   CurrencyPosition(currency: Currency.RUB, balance: 0.0, blocked: null),
    //   CurrencyPosition(currency: Currency.USD, balance: 1000.0, blocked: null)
    // ]
  } else {
    print('Load currencies failed: ${res.asError!.error}');
  }

  // 请求当前的资产组合
  final portfolioBeforeRes = await api.portfolio.load();
  if (portfolioBeforeRes.isValue) {
    final portfolioBefore = portfolioBeforeRes.asValue!.value.payload;
    print('Current portfolio: ${portfolioBefore.positions}');
    // 输出:
    // Current portfolio: [
    //   PortfolioPosition(
    //     figi: BBG0013HGFT4,
    //     ticker: USD000UTSTOM,
    //     isin: null,
    //     instrumentType: InstrumentType.currency,
    //     balance: 1000.0,
    //     blocked: 0.0,
    //     expectedYield: null,
    //     lots: 1,
    //     averagePositionPrice: null,
    //     averagePositionPriceNoNkd: null,
    //     name: 美元
    //   )
    // ]
  } else {
    print('Load portfolio failed: ${portfolioBeforeRes.asError!.error}');
  }

  // 查找股票:苹果公司
  String figi;
  final searchRes = await api.market.searchByTicker('AAPL');
  if (searchRes.isValue) {
    final searchData = searchRes.asValue!.value.payload;
    if (searchData.total > 0) {
      final instrument = searchData.instruments.first;
      print('Found instrument: $instrument');
      // 输出:
      // Found instrument: MarketInstrument(
      //   figi: BBG000B9XRY4,
      //   ticker: AAPL,
      //   isin: US0378331005,
      //   minPriceIncrement: 0.01,
      //   faceValue: null,
      //   lot: 1,
      //   minQuantity: null,
      //   currency: Currency.USD,
      //   name: 苹果,
      //   type: InstrumentType.stock
      // )

      figi = instrument.figi;
    } else {
      print('Nothing found');
      return;
    }
  } else {
    print('Search failed: ${searchRes.asError!.error}');
    return;
  }

  // 购买苹果公司的股票
  final orderRes = await api.orders.limitOrder(figi, OperationType.buy, 100, 1);
  if (orderRes.isValue) {
    final placedOrder = orderRes.asValue!.value.payload;
    print('Order placed: $placedOrder');
    // 输出:
    // Order placed: PlacedLimitOrder(
    //   orderId: 42b991c7-071a-408c-aae7-76a510d9637f,
    //   operation: OperationType.buy,
    //   status: OrderStatus.fill,
    //   rejectReason: null,
    //   message: null,
    //   requestedLots: 1,
    //   executedLots: 1,
    //   commission: null
    // )
  } else {
    print('Place limit order failed: ${orderRes.asError!.error}');
  }

  // 在沙盒中交易会立即完成
  // 请求购买后的资产组合
  final portfolioAfterRes = await api.portfolio.load();
  if (portfolioAfterRes.isValue) {
    final portfolioAfter = portfolioAfterRes.asValue!.value.payload;
    print('Portfolio after purchase: ${portfolioAfter.positions}');
    // 输出:
    // Portfolio after purchase: [
    //   PortfolioPosition(
    //     figi: BBG000B9XRY4,
    //     ticker: AAPL,
    //     isin: US0378331005,
    //     instrumentType: InstrumentType.stock,
    //     balance: 1.0,
    //     blocked: 0.0,
    //     expectedYield: null,
    //     lots: 1,
    //     averagePositionPrice: null,
    //     averagePositionPriceNoNkd: null,
    //     name: 苹果
    //   ),
    //   PortfolioPosition(
    //     figi: BBG0013HGFT4,
    //     ticker: USD000UTSTOM,
    //     isin: null,
    //     instrumentType: InstrumentType.currency,
    //     balance: 900.0,
    //     blocked: 0.0,
    //     expectedYield: null,
    //     lots: 0,
    //     averagePositionPrice: null,
    //     averagePositionPriceNoNkd: null,
    //     name: 美元
    //   )
    // ]
  } else {
    print('Load portfolio failed: ${portfolioAfterRes.asError!.error}');
  }

  // 订阅错误事件
  api.streaming.onError((event) {
    print('Error: ${event.payload}');
  });

  // 订阅流结束事件
  api.streaming.onDone(() {
    print('Streaming done');
  });

  // 订阅蜡烛图事件
  api.streaming.candle.subscribe(
    figi,
    StreamingCandleInterval.fiveMin,
    (event) {
      print('Candle: ${event.payload}');
      // 输出:
      // Candle: StreamingCandle(
      //   figi: BBG000B9XRY4,
      //   interval: StreamingCandleInterval.fiveMin,
      //   o: 133.73,
      //   c: 133.73,
      //   h: 133.73,
      //   l: 133.7,
      //   v: 3674,
      //   time: 2021-04-22 19:05:00.000
      // )
    },
  );
}

更多关于Flutter金融投资插件tinkoff_invest的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter金融投资插件tinkoff_invest的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中使用tinkoff_invest插件的简单示例代码。tinkoff_invest插件允许你与Tinkoff Investments API进行交互,进行股票交易、获取市场数据等操作。

首先,确保你已经在pubspec.yaml文件中添加了tinkoff_invest依赖:

dependencies:
  flutter:
    sdk: flutter
  tinkoff_invest: ^最新版本号 # 请替换为当前最新版本号

然后,运行flutter pub get来安装依赖。

接下来,我们需要初始化Tinkoff Investments API客户端。这通常涉及到设置API令牌,你可以从Tinkoff Investments的开发者控制台获取这个令牌。

以下是一个基本的示例代码,展示如何初始化客户端并进行一个简单的获取用户账户信息的请求:

import 'package:flutter/material.dart';
import 'package:tinkoff_invest/tinkoff_invest.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  TinkoffInvestClient? _client;
  String? _accountInfo;

  @override
  void initState() {
    super.initState();
    // 替换为你的Tinkoff Investments API令牌
    final String apiToken = 'your_api_token_here';

    // 初始化Tinkoff Invest客户端
    _client = TinkoffInvestClient(apiToken: apiToken);

    // 获取用户账户信息
    _getUserAccountInfo();
  }

  Future<void> _getUserAccountInfo() async {
    try {
      final account = await _client!.getAccounts();
      if (account.isNotEmpty) {
        setState(() {
          _accountInfo = 'Account ID: ${account.first.id}, Balance: ${account.first.balance?.amount ?? 0}';
        });
      } else {
        setState(() {
          _accountInfo = 'No accounts found.';
        });
      }
    } catch (e) {
      setState(() {
        _accountInfo = 'Error: ${e.message ?? 'Unknown error'}';
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Tinkoff Invest Example'),
        ),
        body: Center(
          child: Text(_accountInfo ?? 'Loading...'),
        ),
      ),
    );
  }
}

注意事项:

  1. API Token: 确保你已经从Tinkoff Investments开发者控制台获取了有效的API令牌,并将其替换为your_api_token_here
  2. 错误处理: 在实际应用中,你应该添加更详细的错误处理逻辑,以处理各种可能的API错误情况。
  3. 权限和网络配置: 确保你的应用有适当的网络权限配置,以便能够与Tinkoff Investments API进行通信。

依赖项配置

确保你的AndroidManifest.xmlInfo.plist(对于iOS)文件中有适当的网络权限配置。例如,在AndroidManifest.xml中:

<uses-permission android:name="android.permission.INTERNET"/>

在iOS中,通常不需要额外的配置,除非你有特定的网络要求。

这个示例代码只是一个起点,tinkoff_invest插件提供了许多其他功能,如获取市场数据、下单交易等,你可以查阅官方文档以获取更多详细信息和示例。

回到顶部