Skip to content

Commit

Permalink
finished history and optionchain
Browse files Browse the repository at this point in the history
  • Loading branch information
jbertovic committed Jun 14, 2020
1 parent a9d2f54 commit a638b47
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 35 deletions.
29 changes: 27 additions & 2 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,35 @@ an example usage piped into jq running on linux
}
```

## CLI commands

```
>tdacli --help
TDAmeritrade API CLI 0.1.0
Command Line Interface into tdameritradeclient rust library
USAGE:
tdacli [SUBCOMMAND]
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
SUBCOMMANDS:
account Retrieve account information for <account_id>
help Prints this message or the help of the given subcommand(s)
history Retrieve history for one <symbol>.
optionchain Retrieve option chain for one <symbol>
quote Retrieve quotes for requested symbols
userprincipals Retrieves User Principals
A valid token must be set in env variable: TDAUTHTOKEN.
'*' indicates default value in subcommand help information.
```


### TODO

- [ ] Review how args are entered - Not sure subcommand `[ARGS]` are being grabbed properly
- [ ] finish off History and OptionChain subcommands
- [ ] add option for date calculations on History epoch data stamps
- [ ] Consider adding date conversion using chrono package
- [ ] once orders are complete on [TDAClient](https://github.com/jbertovic/tdameritradeclient) than to new subcommand
2 changes: 1 addition & 1 deletion src/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ pub fn account(c: &TDAClient, args: &ArgMatches) {
}
println!("{}", resp)
}
None => println!("{{ \"error\": \"Missing account_id\"}}"),
None => println!("{{ \"error\": \"Missing account_id\" }}"),
}
}
62 changes: 42 additions & 20 deletions src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
use clap::{App, Arg, SubCommand, ArgMatches, AppSettings};
use clap::{App, Arg, SubCommand, ArgMatches, AppSettings, ArgGroup};

pub fn cli_matches<'a>() -> ArgMatches<'a> {
App::new("TDAmeritrade API CLI")
.version(crate_version!())
.setting(AppSettings::VersionlessSubcommands)
.about("CLI Interface into tdameritradeclient rust library")
.about("Command Line Interface into tdameritradeclient rust library")
.subcommand(SubCommand::with_name("userprincipals").about("Retrieves User Principals"))
.subcommand(
SubCommand::with_name("account")
.about("Retrieve account information for <account_id>")
.arg(
Arg::with_name("account_id")
//.takes_value(true)
//.index(1)
.takes_value(true)
.required(true)
.help("Retrieves account information for linked account_id")
)
.arg(
Expand All @@ -28,9 +28,10 @@ pub fn cli_matches<'a>() -> ArgMatches<'a> {
)
.subcommand(
SubCommand::with_name("quote")
.about("Retrieve quotes for [symbols]")
.about("Retrieve quotes for requested symbols")
.arg(Arg::with_name("symbols")
.help("Retrieves quotes of supplied [symbols] in format \"sym1,sym2,sym3\""
.required(true)
.help("Retrieves quotes of supplied <symbols> in format \"sym1,sym2,sym3\""
))
)
.subcommand(
Expand All @@ -40,7 +41,7 @@ pub fn cli_matches<'a>() -> ArgMatches<'a> {
Arg::with_name("symbol")
//.takes_value(true)
.required(true)
.help("Retrieves history of supplied [symbol]")
.help("Symbol of instrument.")
)
.arg(
Arg::with_name("period_type")
Expand Down Expand Up @@ -76,21 +77,30 @@ pub fn cli_matches<'a>() -> ArgMatches<'a> {
.takes_value(true)
.help("Defines end date epoch format. Default is previous trading day.")
)
.after_help("Think of the frequency as the size of a candle on the chart or how to divide the ticks. \n\
and the period as the term or total length of the history. \n\
'*' indicates default value.")
)
.subcommand(
SubCommand::with_name("optionchain")
.about("Retrieve option chain for one <symbol>")
.arg( // symbol shouldn't be an argument with value but ONLY the value
Arg::with_name("symbol")
//.takes_value(true)
.required(true)
.help("Retrieves history of supplied [symbol]")
.help("Symbol of underlying instrument.")
)
.arg(
Arg::with_name("contract_type")
.long("ctype")
.takes_value(true)
.help("Type of contract to return in chain. <CALL, PUT or ALL (default)>")
Arg::with_name("call")
.short("c")
.help("Retrieve CALL contract types only.")
)
.arg(
Arg::with_name("put")
.short("p")
.help("Retrieve PUT contract types only.")
)
.group(ArgGroup::with_name("contract_type")
.args(&["call", "put"])
)
.arg(
Arg::with_name("strike_count")
Expand All @@ -101,30 +111,33 @@ pub fn cli_matches<'a>() -> ArgMatches<'a> {
.arg(
Arg::with_name("quotes")
.short("q")
.help("Include quotes for options in the option chain. Default is NOT included")
.help("Include underlying instrument quote.")
)
.arg(
Arg::with_name("strategy")
.long("strategy")
.takes_value(true)
.help("Returns strategy chain. Values: <SINGLE (default), COVERED, VERTICAL, CALENDAR, STRANGLE, STRADDLE, \
.help("Returns strategy chain. Values: <SINGLE*, COVERED, VERTICAL, CALENDAR, STRANGLE, STRADDLE, \
BUTTERFLY, CONDOR, DIAGONAL, COLLAR, or ROLL>")
)
.arg(
Arg::with_name("interval")
.long("interval")
.takes_value(true)
.help("Strike interval for spread strategy chains. To used with <strategy> argument.")
)
.arg(
Arg::with_name("strike")
.long("strike")
.short("x")
.takes_value(true)
.help("Return options only at specified strike price")
)
.arg(
Arg::with_name("range")
.long("range")
.takes_value(true)
.help("Specify range: <ALL (default), ITM, NTM, OTM, SAK, SBK, or SNK>")
.help("Specify range: <ALL*, ITM, NTM, OTM, SAK, SBK, or SNK>")
)
.arg(
Arg::with_name("from")
Expand All @@ -139,15 +152,24 @@ pub fn cli_matches<'a>() -> ArgMatches<'a> {
.arg(
Arg::with_name("exp_month")
.long("expm")
.short("m")
.takes_value(true)
.help("Return only options expiring in given month <JAN, FEB..>. Default is ALL.")
)
.arg(
Arg::with_name("option_type")
.long("otype")
.takes_value(true)
.help("Standard or Non-standard contracts: <S, NS, ALL (default)>")
Arg::with_name("typeS")
.short("s")
.help("Standard contracts only.")
)
.arg(
Arg::with_name("typeNS")
.short("n")
.help("Non-Standard contracts only.")
)
.group(ArgGroup::with_name("option_type")
.args(&["typeS", "typeNS"])
)
.after_help("'*' indicates default value.")
)
.after_help("A valid token must be set in env variable: TDAUTHTOKEN.\r\n'*' indicates default value in subcommand help information.")
.get_matches()
Expand Down
3 changes: 2 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ use tdameritradeclient::TDAClient;
fn main() {
let matches = cli::cli_matches();

let c = TDAClient::new(env::var("TDAUTHTOKEN").unwrap());
let c = TDAClient::new(env::var("TDAUTHTOKEN")
.expect("Token is missing inside env variable TDAUTHTOKEN"));

match matches.subcommand() {
("userprincipals", Some(_)) => account::userprincipals(&c),
Expand Down
28 changes: 17 additions & 11 deletions src/quote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,17 @@ pub fn optionchain(c: &TDAClient, args: &ArgMatches) {
Some(symbol) => {
let mut param: Vec<OptionChain> = Vec::new();
// determine query parameters
if args.is_present("ctype") {
param.push(OptionChain::ContractType(args.value_of("ctype").unwrap()));
if args.is_present("call") {
param.push(OptionChain::ContractType("CALL"));
}
if args.is_present("xcount") {
param.push(OptionChain::StrikeCount(args.value_of("xcount").unwrap()
if args.is_present("put") {
param.push(OptionChain::ContractType("PUT"));
}
if args.is_present("strike_count") {
param.push(OptionChain::StrikeCount(args.value_of("srike_count").unwrap()
.parse().expect("strike count should be a positive integer")));
}
if args.is_present("q") {
if args.is_present("quotes") {
param.push(OptionChain::IncludeQuotes(true));
}
if args.is_present("strategy") {
Expand All @@ -73,8 +76,8 @@ pub fn optionchain(c: &TDAClient, args: &ArgMatches) {
param.push(OptionChain::Interval(args.value_of("interval").unwrap()
.parse().expect("strike interval should be a number")));
}
if args.is_present("x") {
param.push(OptionChain::Strike(args.value_of("x").unwrap()
if args.is_present("strike") {
param.push(OptionChain::Strike(args.value_of("strike").unwrap()
.parse().expect("specified strike price should be a number")));
}
if args.is_present("range") {
Expand All @@ -86,11 +89,14 @@ pub fn optionchain(c: &TDAClient, args: &ArgMatches) {
if args.is_present("to") {
param.push(OptionChain::ToDate(args.value_of("to").unwrap()));
}
if args.is_present("expm") {
param.push(OptionChain::ExpireMonth(args.value_of("expm").unwrap()));
if args.is_present("exp_month") {
param.push(OptionChain::ExpireMonth(args.value_of("exp_month").unwrap()));
}
if args.is_present("typeS") {
param.push(OptionChain::OptionType("S"));
}
if args.is_present("otype") {
param.push(OptionChain::OptionType(args.value_of("otype").unwrap()));
if args.is_present("typeNS") {
param.push(OptionChain::OptionType("NS"));
}
let response: String = c.getoptionchain(&symbol, &param);
println!("{}", response)
Expand Down

0 comments on commit a638b47

Please sign in to comment.