Giter Site home page Giter Site logo

d-e-s-o / apca Goto Github PK

View Code? Open in Web Editor NEW
121.0 5.0 36.0 1.91 MB

A crate for interacting with the Alpaca API at alpaca.markets.

License: GNU General Public License v3.0

Rust 100.00%
alpaca-markets alpaca alpaca-trading-api alpaca-api rust rust-library rust-crate

apca's People

Contributors

ajmwagar avatar all8up avatar behos avatar botezantechnologic avatar cakekindel avatar cemlyn007 avatar d-e-s-o avatar dependabot[bot] avatar dgoulet avatar gadersd avatar jorelius avatar naltun avatar nobles5e avatar varonroy avatar zjijz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

apca's Issues

Discussion: GPL?

Just wanted to comment to the author: GPL seems like an extreme choice for a stock trading library as opposed to something like the MIT license. It's my understanding that anyone using this library is legally obligated to release their source code to the public. Is that incorrect?

Support more Trade properties

Hello!

Really liking your Rust API! Was just wondering if you might entertain the idea of supporting more properties for the Trade type? In particular I would like to the trade exchange to be supported. I am more than happy to work on an MR ๐Ÿ˜€

Looking forward to hearing from you,

Kind regards,

Cemlyn

Calendar date/time.

Given that all (most?) of the other date times are represented in UTC, does it make sense for calendar to represent the day/open/close in local (or is it exchange?) timezone? This led me on a merry chase trying to figure out why clock and calendar were not working together to find the "next" valid trading day, i.e. they are in different timezones and it was going wacked before I started dumping the data and noticed it......

Support filtering by symbols in GET /v2/orders

I'd like to be able to filter open orders by a list of symbols.

The Alpaca API allows us to do this via the symbols query parameter. Which takes a comma-delimited list of stock tickers. (i.e. "AAPL,TSLA,MSFT")

I'll be working on a PR, however, I'm not sure how you'd like to expose this via the OrdersReq struct. Ideally, we can use the existing asset::Symbol struct. However, that would only work if all the Symbols were in string form (not Symbol::Id).

What are your thoughts @d-e-s-o ?

Create a mock test client?

If I am reading some of the data tests correctly, it looks like the tests are pulling API keys from the environment and talking to the API? For testing, would it not be better to mock the client responses to remove environment and connectivity dependencies?

No crypto support

Alpaca recently added support for cryptocurrency trading, but apca seems to not be able to handle the new "crypto" asset class. When I attempted to request my positions I received the error: Conversion(Json(Error("unknown variant 'crypto', expected 'us_equity'"))).

Oauth support?

https://alpaca.markets/learn/connecting-to-oauth/

How useful is this? If I am understanding correctly, to be able to run commands as a given user, the APCA_API_KEY_ID and APCA_API_SECRET_KEY need to be available in the environment or the tool should enable OAUTH permissions, allowing the user to log into their account and providing the CLI with an authorization code?

The biggest open questions I have are:

  1. How would you provide a redirect URL to a command line utility?
  2. Does this enable anything that can't be done with APCA_API_KEY_ID/APCA_API_SECRET_KEY?

Thanks for helping me understand this.

Live trading example not updated

Hey!

.subscribe::<RealtimeData<IEX, Bar, Quote, Trade>>() is not working, as RealTimeData accepts 1 generic S with Source trait.

an obvious fix is .subscribe::<RealtimeData<IEX>>()

Downloading stock price data freezes

I tried to download stock price data via the code below.

let request = BarReq {
              symbol: stock_symbol,
              limit: None,
              start: *start_time,
              end: *end_time,
              page_token: None,
              timeframe: timeframe,
              adjustment: Some(Adjustment::All)
            };

let bars = block_on(self.client.issue::<bars::Get>(&request)).unwrap();

However, after downloading the data for some of the assets, the block_on code freezes and never unwraps. I assume this is because I am exceeding Alpaca's request limit, but the code should either unwrap into an error or wait until Alpaca will receive further requests.

Why is there no calendar module?

I need the functionality to get the market opening and close times for arbitrary dates, but there seems to be no calendar module.

Issue or missunderstanding related to subscriptions.

Given that Alpaca limits websocket connections to 1 per account, I am intending to write a small, very simple, proxy. I have it basically working with one significant annoyance related to handling subscription changes. The outline is trivial, I start the proxy up, open the data stream and the order status stream, sit in a loop select!(ing) for data which is simply forwarded along along to some tcp connections. No security, nothing fancy, just something to sit within my network so I don't get locked out when I have long running live testing.

Now, in doing this, I ran into a problem with the subscription change mechanism and I'm hoping I'm just missing something but I'm having no luck figuring it out. Basically when you add/remove symbol subscriptions all the examples that I found use the "drive" function. The issue I've run into is that I believe the proper way to handle this is to add an UnorderedFutures container which I would add the subscription futures to so I can integrate them into my existing loop to be polled and cleaned up without interrupting the other streams which are already being polled. I.e.

// Pseudo code mostly.
select! {
  command = commands.recv() => match .. ok/etc/match command  {
    Commands::ChangeSubscriptions(...) => ... make market_data container ...
      // Change the subscriptions using the item returned by the connection command.
      let subscribe = subscription.subscribe(&market_data).boxed();
      // Post the future to be resolved.
      subscriptions.push(subscribe.fuse());
  }
  subscription_result = subscriptions.next() ... // Polls the subscription change futures.
  update = orders.next ... etc // Handles the order update stream.
  data = data.next ... etc // Handles the subscription stream.
}

Seems straight forward with one issue. The 'subscribe' function takes a mut self and the resulting future captures items requiring that mut self. So, I end up with a future I can't push out of the scope and as such can't push into the container....

I'd love to be told I'm missing something as the work arounds seem less than pleasant.. I think from a logical point of view the intention is at least correct. The work around is scoping the subscribe and then duplicating the other 3 stream polls so I don't miss any data or add large latencies into the proxy.

Thoughts, suggestions, anything is welcome...

Adding support for crypto streaming

Hey!
from what I've tried the repo does not support crypto streaming, that is due to a different path structure from the regular streaming api.
I think it's very important, because you can trade crypto 24/7 so you don't need to wait for market open times to test your code.
I'm new to rust, but I think I know how to change that, and if I'll get some timely support I can work on a PR for that.
basically start by making the Source trait return the URL instead of the STR, than incorporate that to ApiInfo.

automatic websocket reconnection

ref discussion #61

would it be possible to request a feature for automatic websocket reconnection?

I think the error is from here: https://github.com/snapview/tungstenite-rs/blob/57d9e23939085c342949e62df799d75ed7c27d2f/src/protocol/mod.rs#L619

I'm still new~ish to rust so it may be entirely possible that I'm just using a bad design pattern to connect to Alpaca and keep the connection refreshed. I easily get 10k+ quotes per second for a long stretches of time before my program crashes on the error in question.

Implementing Options Trading for Beta Users in Alpaca's Paper Environment

Alpaca has recently introduced support for options trading for selected beta users in its paper trading environment.

As a new Rust developer, I'm interested in exploring how I could contribute to expanding this feature. Although relatively new to this language, I am eager to apply my growing skills to real-world practices, while also learning from more experienced developers.

I am looking forward to any guidance or suggestions the community can offer.

Add support for notional orders

Hi!

Great work with the client SDK! I started using it and tracking some changes in a fork to add some features that I needed.

One of them is adding support for notional orders. This affects the types of several different API objects, so I'd like to hear your opinion on how to support this properly (I made some hacky changes to get things working but haven't written tests yet).

#16

What do you think?

Invalid Crypto Time in Force

I understand that cryptocurrency support is not planned for apca, but I would like to document this issue in case cryptocurrency support becomes planned. The following code

let request = order::OrderReqInit { type_: order::Type::Market, ..Default::default() }.init("ETHUSD", Buy, order::Amount::quantity(order_quantity));
let order = client.issue::<order::Post>(&request).await.unwrap();

throws the error
thread 'main' panicked at 'called 'Result::unwrap()' on an 'Err' value: Endpoint(InvalidInput(Ok(ErrorMessage { code: 42210000, message: "invalid crypto time_in_force" })))'

Old version of tokio

Can you please update the version of tokio to 1.0?
It breaks when I use tokio 1.0
#[tokio::test]
async fn create_paper_client() -> Result<()> {
let client = broker_sandbox_client()?;

    let f =  client.issue::<account::Get>(());
    let info = f.await?;
    assert_eq!(info.id, account::Id(Uuid::new_v4()));
    Ok(())
}

not currently running on the Tokio runtime.
thread 'broker::alpaca::tests::create_paper_client' panicked at 'not currently running on the Tokio runtime.', /Users/mohammedyounusraza/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.2.24/src/runtime/handle.rs:118:28
stack backtrace:

Proposal: Use a dedicated data type for stock symbols instead of String

Proposal: Use a stack-allocated dedicated Symbol type such as stock-symbol.

Benefits:

  • A dedicated type is more self-explanatory than passing around strings
  • Should be much faster than doing many tiny heap allocated String symbols
  • This will allow us to implement Copy, making many operations much simpler
  • Can provide additional validation of the underlying strings

support for Latest Multi Trades

The alpaca endpoint GET/v2/stocks/trades/latest supports getting latest trades for multiple symbols at once. This would be useful for performance and avoiding quota limits.

I'd be happy to work up a PR in similar vein to the existing last_quote mod if of interest

Expose paging variables for GET /v2/account/activities endpoints

Hey d-e-s-o,

I've been attempting to pull trade execution info from the Alpaca API.

As you can see from their documentation you need to use the page_token and page_size Query params to get more than the last 100 trades.

We can also specify desc or asc to set the direction.

Would it be possible to expose these query params?

I'd attempt to do it myself, but I'm not entirely sure how your Endpoint! macro works.

Hook up portfolio history

We should add bindings for the portfolio endpoint. This shouldn't be terribly hard. Find an existing commit introducing bindings for an endpoint and adjust it accordingly. Then add tests. Once done, it would be great to also make this functionality available to apcacli, by adding a sub-command.

Parent type for `RequestError<_>`

I'm new in rust and I'm not sure how to achieve this. I created BrokerClient trait as common interface - in my app it could be multiple brokers. What should I use in BrokerError for AlpacaError variant to satisfy compiler. I tried anyhow - doesn't work.

use std::{error::Error, sync::Arc};

use anyhow::Result;
use apca::{api::v2::account, Client as AlpacaClient};

use crate::{
    api::objects::Account,
    strategy_manager::{Broker, Order},
};

#[derive(Debug, thiserror::Error)]
enum BrokerError {
    #[error("Alpaca error: {0}")]
    AlpacaError(#[from] anyhow::Error),
}

#[axum::async_trait]
pub trait BrokerClient: Send + Sync {
    async fn get_account(&self) -> Result<Account>;
    async fn get_positions(&self) -> Result<(), BrokerError>;
    async fn get_orders(&self) -> Result<(), BrokerError>;
    async fn place_order(&self, order: &Order, broker: &Broker) -> Result<(), BrokerError>;
    async fn cancel_order(&self) -> Result<(), BrokerError>;
    async fn cancel_all_orders(&self) -> Result<(), BrokerError>;
}

#[axum::async_trait]
impl BrokerClient for Arc<AlpacaClient> {
    async fn get_account(&self) -> Result<apca::api::v2::account::Account> {
        let res = self.issue::<account::Get>(&()).await;
        res
    }
    async fn get_positions(&self) -> Result<(), BrokerError> {
        Ok(())
    }
    async fn get_orders(&self) -> Result<(), BrokerError> {
        Ok(())
    }

    async fn place_order(&self, order: &Order, broker: &Broker) -> Result<(), BrokerError> {
        Ok(())
    }
    async fn cancel_order(&self) -> Result<(), BrokerError> {
        Ok(())
    }
    async fn cancel_all_orders(&self) -> Result<(), BrokerError> {
        Ok(())
    }
}

image

UUID using Getrandom and Rand prevents compiling to WASM

Compiling any code to wasm32-unknown-unknown fails to build because of the optional Rand and Getrandom dependencies of UUID. Would it be possible to disable that option and force UUID to accomplish the same result without inheriting those child dependencies?

(Sorry for the near duplicates; trying to start a new project before vacation, and I will provide more help and clarity within a couple of weeks!)

Optionally use rustls instead of hyper-tls

I'm cross-compiling a bot to x86_64-unknown-linux-musl. This crate requires hyper-tls, which requires native-tls, which uses OpenSSL. The build script for OpenSSL always fails, as it cannot find the proper cross compiler. While I could install a cross-compiler and proceed as normal, this is generally not recommended. Instead, crates can often use rustls instead of OpenSSL, which does not require a cross-compiler.

The hyper crate says that rustls is possible. I'm not 100% sure what specific logic is needed to do this, but not much will change anyway. The hyper-tls connector just needs to be swapped with a rustls connector.

This would be an opt-in feature, but having a feature flag for this would make cross-compiling and no-dynamic-library builds much easier.

I will be implementing this in a public fork regardless, since I need it for my bot. Would you like it pulled into the main repository when ready?

Thanks!

Tokio using Mio prevents compiling to WASM

Compiling any code to wasm32-unknown-unknown fails to build because of the optional Mio dependency of Tokio. Would it be possible to disable that option and force Tokio to accomplish the same result without inheriting that child dependency?

unknown variant ``, expected one of `simple`, `bracket`, `oco`, `oto`

I've seen the following failure a couple of times in CI now (example):

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Endpoint(Conversion(Json(Error("unknown variant ``, expected one of `simple`, `bracket`, `oco`, `oto`", line: 1, column: 21996))))', src/api/v2/orders.rs:191:52
---- api::v2::orders::tests::list_orders stdout ----

This may be related to the order class change 569616c. I have not yet been able to reproduce locally, but haven't tried hard either. My suspicion is that leg orders don't have the order class property populated correctly, but I haven't verified that.

@husafan, have you seen this problem during your testing?

example of streaming data with handlers

I'm trying to adapt stream-realtime-data.rs to use specific handlers for the different types of Data.

I'm pretty sure this isn't idiomatic rust, but I can't figure out how to do it with matches arms.

let () = stream
    // Stop after receiving and printing 50 updates.
    // .take(50)
    .map_err(Error::WebSocket)
    .try_for_each(|result| async {
        result
            .map(|data| {
                if data.is_bar() {
                    // use a bar handler
                    println!("got bar {:?}", data);
                } else if data.is_quote() {
                    // use a quote handler
                    println!("got quote {:?}", data);
                } else if data.is_trade() {
                    // use a trade handler
                    println!("got trade {:?}", data);
                } else {
                    // use an "other" handler
                    println!("got other {:?}", data);
                };
            })
            .map_err(Error::Json)
    })
    .await
    .unwrap();

I'm coming from Alpaca's Go client and am learning Rust in the process.

Would it be possible to update the example to make it a little more clearer? I can submit a PR once I figure it out, as well as populate a few more beginner friendly examples like the ones listed in Alpaca's Go Repo.

Also, I know this isn't an issue - perhaps consider opening up the "discussions" area of this github repo. Thanks for your time and such a great library, I hope to use it extensively in the coming weeks!

Suggestion wrt paging

As mentioned in the subject, this is not an issue; rather is it a suggestion related to issue #5 which is closed since quite a bit of time now.

I think that in order to improve the ergonomics of the crate, it might be worth it to just hide the fact that some paging occurs under the hood and fetch data on demand. That is, rather than returning a collection of events, the api would return a stream of events (we're using async+tokio anyways).

Should it be of any interest to you or the apca users community, I readily have a generic working solution for this issue in apca_datav2 (look at PagedStream<T> lines 266+ in this file).

If you don't like the idea, I'd totally understand that you'd just reject/close this issue.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.