基本功能示例

大约 4 分钟

老虎Open API SDK提供了丰富的接口来调用老虎的服务,本章节将对老虎API的核心功能进行一一演示:包括查询行情,订阅行情,以及调用API进行交易

查询行情

以下为一个最简单的调用老虎API的示例,演示了如何调用Open API来主动查询股票行情。接下来的例子分别演示了如何调用Open API来进行交易与订阅行情。除上述基础功能外,Open API还支持查询、交易多个市场的不同标的,以及其他复杂请求。对于其他Open API支持的接口和请求,请在快速入门后阅读文档正文获取列表及使用方法,并参考快速入门以及文档中的例子进行调用

为方便直接复制运行,以下的说明采用注释的形式

using System;
using Newtonsoft.Json;
using TigerOpenAPI.Common;
using TigerOpenAPI.Common.Enum;
using TigerOpenAPI.Common.Util;
using TigerOpenAPI.Config;
using TigerOpenAPI.Model;
using TigerOpenAPI.Quote;
using TigerOpenAPI.Quote.Model;
using TigerOpenAPI.Quote.Response;

namespace Test
{
  public class Demo
  {
    private static TigerConfig config;
    private static QuoteClient quoteClient;

    static Demo ()
    {
      TigerConfig.LogDir = "/data0/logs/tiger-openapi-cs";
      config = new TigerConfig()
      {
        ConfigFilePath = "/data0/tiger_config",
        FailRetryCounts = 2, // (optional) range:[1, 5],  default is 2
        Language = Language.en_US,   // (optional) default is en_US
        TimeZone = CustomTimeZone.HK_ZONE  // (optional) default is HK_ZONE
      };
      quoteClient = new QuoteClient(config);
    }

    static async Task Main(string[] args)
    {

      TigerRequest<QuoteKlineResponse> request = new TigerRequest<QuoteKlineResponse>()
      {
        ApiMethodName = QuoteApiService.KLINE,
        ModelValue = new QuoteKlineModel()
        {
          Symbols = new List<string> { "AAPL" },
          Period = KLineType.day.Value,
          BeginTime = DateUtil.ConvertTimestamp("2023-03-01", CustomTimeZone.NY_ZONE),
          EndTime = DateUtil.CurrentTimeMillis(),
          Rigth = RightOption.br
        }
      };
      QuoteKlineResponse? response = await quoteClient.ExecuteAsync(request);
      if (response is not null && response.IsSuccess())
      {
        ApiLogger.Info("request success:" + JsonConvert.SerializeObject(response));
      }
      else
      {
        ApiLogger.Info("request fail:" + JsonConvert.SerializeObject(response));
      }
    }
  }
}

订阅行情

除了选择主动查询的方式(见快速入门-查询行情部分),Open API还支持订阅-接受推送的方式来接收行情等信息,具体见下例。需要注意的是,订阅推送相关的请求均为异步处理,故需要用户自定义回调函数,与中间函数进行绑定。某个事件发生,或有最新信息更新被服务器推送时,程序会自动调用用户自定义的回调函数并传入返回接口返回的数据,由用户自定义的回调函数来处理数据。

  1. 定义回调接口
using System;
using System.Text.Json.Nodes;
using Newtonsoft.Json;
using TigerOpenAPI.Common;
using TigerOpenAPI.Common.Util;
using TigerOpenAPI.Push;
using TigerOpenAPI.Push.Model;
using TigerOpenAPI.Quote.Pb;

namespace Test
{
  public class DefaultApiComposeCallback : IApiComposeCallback
  {
    public DefaultApiComposeCallback()
    {
    }

    void IApiComposeCallback.ConnectionAck()
    {
      ApiLogger.Info("connect success.");
    }

    void IApiComposeCallback.ConnectionAck(int serverSendInterval, int serverReceiveInterval)
    {
      ApiLogger.Info($"connect success. serverSendInterval:{serverSendInterval}," +
        $" serverReceiveInterval:{serverReceiveInterval}");
    }

    void IApiComposeCallback.HearBeat(string heartBeatContent)
    {
      ApiLogger.Info("HearBeat:" + heartBeatContent);
    }

    void IApiComposeCallback.ServerHeartBeatTimeOut(string channelId)
    {
      ApiLogger.Warn("ServerHeartBeatTimeOut:" + channelId);
    }

    void IApiComposeCallback.ConnectionClosed()
    {
      ApiLogger.Info("connection closed.");
    }

    void IApiComposeCallback.ConnectionKickout(int errorCode, string errorMsg)
    {
      ApiLogger.Info($"ConnectionKickout, errorCode:{errorCode}, errorMsg:{errorMsg}");
    }

    void IApiComposeCallback.Error(string errorMsg)
    {
      ApiLogger.Error("receive error:" + errorMsg);
    }

    void IApiComposeCallback.Error(int id, int errorCode, string errorMsg)
    {
      ApiLogger.Error($"receive error, id:{id}, errorCode:{errorCode}, errorMsg:{errorMsg}");
    }


    void ISubscribeApiCallback.GetSubscribedSymbolEnd(SubscribedSymbol subscribedSymbol)
    {
      ApiLogger.Info("GetSubscribedSymbolEnd:"
        + JsonConvert.SerializeObject(subscribedSymbol, TigerClient.JsonSet));
    }

    void ISubscribeApiCallback.SubscribeEnd(int id, string subject, string result)
    {
      ApiLogger.Info($"SubscribeEnd, {subject}, id:{id}, result:{result}");
    }

    void ISubscribeApiCallback.CancelSubscribeEnd(int id, string subject, string result)
    {
      ApiLogger.Info($"CancelSubscribeEnd, {subject}, id:{id}, result:{result}");
    }


    void ISubscribeApiCallback.AssetChange(AssetData data)
    {
      ApiLogger.Info("AssetChange:" + data);
    }

    void ISubscribeApiCallback.PositionChange(PositionData data)
    {
      ApiLogger.Info("PositionChange:" + data);
    }

    void ISubscribeApiCallback.OrderStatusChange(OrderStatusData data)
    {
      ApiLogger.Info("OrderStatusChange:" + data);
    }

    void ISubscribeApiCallback.OrderTransactionChange(OrderTransactionData data)
    {
      ApiLogger.Info("OrderTransactionChange:" + data);
    }


    void ISubscribeApiCallback.QuoteAskBidChange(QuoteBBOData data)
    {
      ApiLogger.Info("QuoteAskBidChange:" + data);
    }

    void ISubscribeApiCallback.QuoteChange(QuoteBasicData data)
    {
      ApiLogger.Info("QuoteChange:" + data);
    }

    void ISubscribeApiCallback.TradeTickChange(TradeTick data)
    {
      ApiLogger.Info("TradeTickChange:"
        + JsonConvert.SerializeObject(data, TigerClient.JsonSet));
    }

    void ISubscribeApiCallback.FullTickChange(TickData data)
    {
      ApiLogger.Info("FullTickChange:" + data);
    }

    void ISubscribeApiCallback.KlineChange(KlineData data)
    {
      ApiLogger.Info("KlineChange:" + data);
    }

    void ISubscribeApiCallback.DepthQuoteChange(QuoteDepthData data)
    {
      ApiLogger.Info("DepthQuoteChange:" + data);
    }

    void ISubscribeApiCallback.FutureAskBidChange(QuoteBBOData data)
    {
      ApiLogger.Info("FutureAskBidChange:" + data);
    }

    void ISubscribeApiCallback.FutureChange(QuoteBasicData data)
    {
      ApiLogger.Info("FutureChange:" + data);
    }

    void ISubscribeApiCallback.OptionAskBidChange(QuoteBBOData data)
    {
      ApiLogger.Info("OptionAskBidChange:" + data);
    }

    void ISubscribeApiCallback.OptionChange(QuoteBasicData data)
    {
      ApiLogger.Info("OptionChange:" + data);
    }

    void ISubscribeApiCallback.StockTopPush(StockTopData data)
    {
      ApiLogger.Info("StockTopPush, market:" + data.Market);
      foreach (StockTopData.Types.TopData topData in data.TopData)
      {
        ApiLogger.Info("StockTopPush, targetName:" + topData.TargetName
            + ", topList:" + topData);
      }
    }

    void ISubscribeApiCallback.OptionTopPush(OptionTopData data)
    {
      ApiLogger.Info("OptionTopPush, market:" + data.Market);
      foreach (OptionTopData.Types.TopData topData in data.TopData)
      {
        ApiLogger.Info("OptionTopPush, targetName:" + topData.TargetName
            + ", topList:" + topData);
      }
    }
  }
}
  1. 进行订阅
using System;
using Newtonsoft.Json;
using TigerOpenAPI.Common;
using TigerOpenAPI.Common.Enum;
using TigerOpenAPI.Common.Util;
using TigerOpenAPI.Config;
using TigerOpenAPI.Model;
using TigerOpenAPI.Push;
using TigerOpenAPI.Quote;
using TigerOpenAPI.Quote.Model;

namespace Test
{
  public class SubscribeDemo
  {
    private static TigerConfig config;

    static SubscribeDemo()
    {
      TigerConfig.LogDir = "/data0/logs/tiger-openapi-cs";
      config = new TigerConfig()
      {
        // 从开发者信息页面导出的配置文件tiger_openapi_config.properties的存放路径
        ConfigFilePath = "/data0/tiger_config",
        FailRetryCounts = 2, // (optional) range:[1, 5],  default is 2
        Language = Language.en_US,   // (optional) default is en_US
        TimeZone = CustomTimeZone.HK_ZONE  // (optional) default is HK_ZONE
      };
    }

    static async Task Main(string[] args)
    {
      IApiComposeCallback callback = new DefaultApiComposeCallback();
      PushClient client = PushClient.GetInstance().Config(config)
        .ApiComposeCallback(callback);
      ApiLogger.Info($"======================{client.GetUrl()}");

      // 建立连接
      client.Connect();

      ISet<string> symbols = new HashSet<string>();
      symbols.Add("AAPL");
      symbols.Add("TSLA");
      // 订阅股票行情
      ApiLogger.Info($"SubscribeQuote:{client.SubscribeQuote(symbols)}");
      // 获取已订阅标的
      ApiLogger.Info($"GetSubscribedSymbols:{client.GetSubscribedSymbols()}");
      Thread.Sleep(TimeSpan.FromSeconds(60));
      // 取消股票行情标的的订阅
      ApiLogger.Info($"CancelSubscribeQuote:{client.CancelSubscribeQuote(symbols)}");
      Thread.Sleep(TimeSpan.FromSeconds(2));
      ApiLogger.Info($"GetSubscribedSymbols:{client.GetSubscribedSymbols()}");
    }
  }
}

下单

交易是Open API的另一个主要功能。此例展示了如何使用Open API对美股AAPL下限价单:

using System;
using Newtonsoft.Json;
using TigerOpenAPI.Common;
using TigerOpenAPI.Common.Enum;
using TigerOpenAPI.Common.Util;
using TigerOpenAPI.Config;
using TigerOpenAPI.Model;
using TigerOpenAPI.Trade;
using TigerOpenAPI.Trade.Model;
using TigerOpenAPI.Trade.Response;

namespace Test
{
  public class TradeDemo
  {
    private static TigerConfig config;
    private static TradeClient tradeClient;

    static TradeDemo()
    {
      TigerConfig.LogDir = "/data0/logs/tiger-openapi-cs";
      config = new TigerConfig()
      {
        ConfigFilePath = "/data0/tiger_config",
        FailRetryCounts = 2, // (optional) range:[1, 5],  default is 2
        Language = Language.en_US,   // (optional) default is en_US
        TimeZone = CustomTimeZone.HK_ZONE  // (optional) default is HK_ZONE
      };
      tradeClient = new TradeClient(config);
    }

    static async Task Main(string[] args)
    {
      ContractItem contract = ContractItem.buildStockContract("AAPL", Currency.USD.ToString());

      TigerRequest<PlaceOrderResponse> request = new TigerRequest<PlaceOrderResponse>()
      {
        ApiMethodName = TradeApiService.PLACE_ORDER,
        ModelValue = PlaceOrderModel.buildLimitOrder(
          "20200821144442583", // tradeClient.GetDefaultAccount,
          contract,
          ActionType.BUY,
          1, 120.0
        )
      };
      // set other parameter
      PlaceOrderModel model = (PlaceOrderModel)request.ModelValue;
      model.TimeInForce = TimeInForce.GTD;
      model.ExpireTime = DateUtil.ConvertTimestamp("2023-03-09 23:59:59",
        SymbolUtil.getZoneIdBySymbol("AAPL", tradeClient.GetConfigTimeZone));
      PlaceOrderResponse? response = await tradeClient.ExecuteAsync(request);
      if (response is not null && response.IsSuccess())
      {
        ApiLogger.Info("request success:" + JsonConvert.SerializeObject(response));
      }
      else
      {
        ApiLogger.Info("request fail:" + JsonConvert.SerializeObject(response));
      }
    }
  }
}
上次编辑于: