基本功能示例
大约 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还支持订阅-接受推送的方式来接收行情等信息,具体见下例。需要注意的是,订阅推送相关的请求均为异步处理,故需要用户自定义回调函数,与中间函数进行绑定。某个事件发生,或有最新信息更新被服务器推送时,程序会自动调用用户自定义的回调函数并传入返回接口返回的数据,由用户自定义的回调函数来处理数据。
- 定义回调接口
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);
}
}
}
}
- 进行订阅
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));
}
}
}
}