Skip to content

Commit

Permalink
Merge pull request #67 from AdalyatNazirov/binance-cli
Browse files Browse the repository at this point in the history
Referes Binance as nuget
  • Loading branch information
Martin-Molinero authored Feb 15, 2022
2 parents 1f1be7e + a0188bc commit a9291fe
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 5 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,7 @@ Options:
--gdax-api-secret TEXT Your Coinbase Pro API secret
--gdax-passphrase TEXT Your Coinbase Pro API passphrase
--gdax-use-sandbox BOOLEAN Whether the sandbox should be used
--binance-organization TEXT The name or id of the organization with the Binance module subscription
--binance-api-key TEXT Your Binance API key
--binance-api-secret TEXT Your Binance API secret
--binance-use-testnet BOOLEAN Whether the testnet should be used
Expand Down
13 changes: 11 additions & 2 deletions lean/commands/live.py
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,10 @@ def _get_default_value(key: str) -> Optional[Any]:
type=bool,
default=lambda: _get_default_value("gdax-use-sandbox"),
help="Whether the sandbox should be used")
@click.option("--binance-organization",
type=str,
default=lambda: _get_default_value("job-organization-id"),
help="The name or id of the organization with the Binance module subscription")
@click.option("--binance-api-key",
type=str,
default=lambda: _get_default_value("binance-api-key"),
Expand Down Expand Up @@ -633,6 +637,7 @@ def live(project: Path,
gdax_api_secret: Optional[str],
gdax_passphrase: Optional[str],
gdax_use_sandbox: Optional[bool],
binance_organization: Optional[str],
binance_api_key: Optional[str],
binance_api_secret: Optional[str],
binance_use_testnet: Optional[bool],
Expand Down Expand Up @@ -776,7 +781,10 @@ def live(project: Path,
gdax_use_sandbox)
elif brokerage == BinanceBrokerage.get_name():
ensure_options(["binance_api_key", "binance_api_secret", "binance_use_testnet"])
brokerage_configurer = BinanceBrokerage(binance_api_key, binance_api_secret, binance_use_testnet)
brokerage_configurer = BinanceBrokerage(_get_organization_id(binance_organization, "Binance"),
binance_api_key,
binance_api_secret,
binance_use_testnet)
elif brokerage == ZerodhaBrokerage.get_name():
ensure_options(["zerodha_api_key",
"zerodha_access_token",
Expand Down Expand Up @@ -909,7 +917,8 @@ def live(project: Path,
gdax_use_sandbox))
elif data_feed == BinanceDataFeed.get_name():
ensure_options(["binance_api_key", "binance_api_secret", "binance_use_testnet"])
data_feed_configurer = BinanceDataFeed(BinanceBrokerage(binance_api_key,
data_feed_configurer = BinanceDataFeed(BinanceBrokerage(_get_organization_id(binance_organization, "Binance"),
binance_api_key,
binance_api_secret,
binance_use_testnet))
elif data_feed == ZerodhaDataFeed.get_name():
Expand Down
3 changes: 3 additions & 0 deletions lean/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@
# The product id of the ZERODHA module
ZERODHA_PRODUCT_ID = 174

# The product id of the Binance module
BINANCE_PRODUCT_ID = 176

# The product id of the SAMCO module
SAMCO_PRODUCT_ID = 173

Expand Down
30 changes: 27 additions & 3 deletions lean/models/brokerages/local/binance.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,19 @@
import click

from lean.components.util.logger import Logger
from lean.constants import BINANCE_PRODUCT_ID
from lean.container import container
from lean.models.brokerages.local.base import LocalBrokerage
from lean.models.config import LeanConfigConfigurer
from lean.models.logger import Option


class BinanceBrokerage(LocalBrokerage):
"""A LocalBrokerage implementation for the Binance brokerage."""
_is_module_installed = False

def __init__(self, api_key: str, api_secret: str, testnet: bool) -> None:
def __init__(self, organization_id: str, api_key: str, api_secret: str, testnet: bool) -> None:
self._organization_id = organization_id
self._api_key = api_key
self._api_secret = api_secret
self._testnet = testnet
Expand All @@ -34,6 +39,16 @@ def get_name(cls) -> str:

@classmethod
def _build(cls, lean_config: Dict[str, Any], logger: Logger) -> LocalBrokerage:
api_client = container.api_client()

organizations = api_client.organizations.get_all()
options = [Option(id=organization.id, label=organization.name) for organization in organizations]

organization_id = logger.prompt_list(
"Select the organization with the {} module subscription".format(cls.get_name()),
options
)

logger.info("""
Create an API key by logging in and accessing the Binance API Management page (https://www.binance.com/en/my/settings/api-management).
""".strip())
Expand All @@ -42,9 +57,11 @@ def _build(cls, lean_config: Dict[str, Any], logger: Logger) -> LocalBrokerage:
api_secret = logger.prompt_password("API secret", cls._get_default(lean_config, "binance-api-secret"))
testnet = click.confirm("Use the testnet?")

return BinanceBrokerage(api_key, api_secret, testnet)
return BinanceBrokerage(organization_id, api_key, api_secret, testnet)

def _configure_environment(self, lean_config: Dict[str, Any], environment_name: str) -> None:
self.ensure_module_installed()

lean_config["environments"][environment_name]["live-mode-brokerage"] = "BinanceBrokerage"
lean_config["environments"][environment_name]["transaction-handler"] = \
"QuantConnect.Lean.Engine.TransactionHandlers.BrokerageTransactionHandler"
Expand All @@ -61,8 +78,13 @@ def configure_credentials(self, lean_config: Dict[str, Any]) -> None:
lean_config["binance-api-url"] = "https://api.binance.com"
lean_config["binance-websocket-url"] = "wss://stream.binance.com:9443/ws"

self._save_properties(lean_config, ["binance-api-key", "binance-api-secret", "binance-use-testnet"])
lean_config["job-organization-id"] = self._organization_id
self._save_properties(lean_config, ["job-organization-id", "binance-api-key", "binance-api-secret", "binance-use-testnet"])

def ensure_module_installed(self) -> None:
if not self._is_module_installed:
container.module_manager().install_module(BINANCE_PRODUCT_ID, self._organization_id)
self._is_module_installed = True

class BinanceDataFeed(LeanConfigConfigurer):
"""A LeanConfigConfigurer implementation for the Binance data feed."""
Expand All @@ -79,6 +101,8 @@ def build(cls, lean_config: Dict[str, Any], logger: Logger) -> LeanConfigConfigu
return BinanceDataFeed(BinanceBrokerage.build(lean_config, logger))

def configure(self, lean_config: Dict[str, Any], environment_name: str) -> None:
self._brokerage.ensure_module_installed()

lean_config["environments"][environment_name]["data-queue-handler"] = "BinanceBrokerage"
lean_config["environments"][environment_name]["history-provider"] = "BrokerageHistoryProvider"

Expand Down

0 comments on commit a9291fe

Please sign in to comment.