quantplay 2.0.22__tar.gz → 2.0.24__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {quantplay-2.0.22 → quantplay-2.0.24}/PKG-INFO +1 -1
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/broker/aliceblue.py +1 -1
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/broker/noren.py +18 -3
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/broker/upstox.py +13 -8
- quantplay-2.0.24/quantplay/strategies/options/intraday/__init__.py +0 -0
- quantplay-2.0.24/quantplay/strategies/options/intraday/ladder.py +65 -0
- quantplay-2.0.24/quantplay/strategies/options/intraday/musk.py +72 -0
- quantplay-2.0.24/quantplay/strategies/options/intraday/short_straddle.py +10 -0
- quantplay-2.0.24/quantplay/utils/__init__.py +0 -0
- quantplay-2.0.24/quantplay/wrapper/__init__.py +0 -0
- quantplay-2.0.24/quantplay/wrapper/aws/__init__.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay.egg-info/PKG-INFO +1 -1
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay.egg-info/SOURCES.txt +11 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/setup.py +1 -1
- quantplay-2.0.24/tests/__init__.py +0 -0
- quantplay-2.0.24/tests/conftest.py +0 -0
- quantplay-2.0.24/tests/wrapper/__init__.py +0 -0
- quantplay-2.0.24/tests/wrapper/aws/__init__.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/README.md +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/pyproject.toml +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/__init__.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/broker/__init__.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/broker/angelone.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/broker/auto_login/__init__.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/broker/auto_login/aliceblue.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/broker/finvasia_utils/__init__.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/broker/finvasia_utils/fa_noren.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/broker/five_paisa.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/broker/flattrade.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/broker/ft_utils/__init__.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/broker/ft_utils/flattrade_utils.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/broker/ft_utils/ft_noren.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/broker/generics/__init__.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/broker/generics/broker.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/broker/iifl_xts.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/broker/kite_utils.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/broker/motilal.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/broker/shoonya.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/broker/uplink/__init__.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/broker/uplink/uplink_utils.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/broker/xts.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/broker/xts_utils/Connect.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/broker/xts_utils/Exception.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/broker/xts_utils/InteractiveSocketClient.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/broker/xts_utils/__init__.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/broker/zerodha.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/exception/__init__.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/exception/exceptions.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/model/__init__.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/model/broker.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/model/generics.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/model/order_event.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/py.typed +0 -0
- {quantplay-2.0.22/quantplay/utils → quantplay-2.0.24/quantplay/strategies}/__init__.py +0 -0
- {quantplay-2.0.22/quantplay/wrapper → quantplay-2.0.24/quantplay/strategies/equities}/__init__.py +0 -0
- {quantplay-2.0.22/quantplay/wrapper/aws → quantplay-2.0.24/quantplay/strategies/equities/intraday}/__init__.py +0 -0
- {quantplay-2.0.22/tests → quantplay-2.0.24/quantplay/strategies/equities/overnight}/__init__.py +0 -0
- {quantplay-2.0.22/tests/wrapper → quantplay-2.0.24/quantplay/strategies/futures}/__init__.py +0 -0
- {quantplay-2.0.22/tests/wrapper/aws → quantplay-2.0.24/quantplay/strategies/futures/overnight}/__init__.py +0 -0
- /quantplay-2.0.22/tests/conftest.py → /quantplay-2.0.24/quantplay/strategies/options/__init__.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/utils/constant.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/utils/exchange.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/utils/number_utils.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/utils/pickle_utils.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/utils/selenium_utils.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay/wrapper/aws/s3.py +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay.egg-info/dependency_links.txt +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay.egg-info/requires.txt +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/quantplay.egg-info/top_level.txt +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/setup.cfg +0 -0
- {quantplay-2.0.22 → quantplay-2.0.24}/tests/wrapper/aws/s3_test.py +0 -0
|
@@ -505,12 +505,9 @@ class Noren(Broker):
|
|
|
505
505
|
"norenordno": "order_id",
|
|
506
506
|
"uid": "user_id",
|
|
507
507
|
"exch": "exchange",
|
|
508
|
-
"remarks": "tag",
|
|
509
|
-
"avgprc": "average_price",
|
|
510
508
|
"prd": "product",
|
|
511
509
|
"trantype": "transaction_type",
|
|
512
510
|
"qty": "quantity",
|
|
513
|
-
"trgprc": "trigger_price",
|
|
514
511
|
"prc": "price",
|
|
515
512
|
"prctyp": "order_type",
|
|
516
513
|
"fillshares": "filled_quantity",
|
|
@@ -538,6 +535,24 @@ class Noren(Broker):
|
|
|
538
535
|
orders_df = orders_df.with_columns(
|
|
539
536
|
pl.col("rorgqty").cast(pl.Int32).alias("pending_quantity")
|
|
540
537
|
)
|
|
538
|
+
if "trgprc" not in orders_df.columns:
|
|
539
|
+
orders_df = orders_df.with_columns(pl.lit(None).alias("trigger_price"))
|
|
540
|
+
else:
|
|
541
|
+
orders_df = orders_df.with_columns(
|
|
542
|
+
pl.col("trgprc").cast(pl.Float64).alias("trigger_price")
|
|
543
|
+
)
|
|
544
|
+
if "avgprc" not in orders_df.columns:
|
|
545
|
+
orders_df = orders_df.with_columns(pl.lit(None).alias("average_price"))
|
|
546
|
+
else:
|
|
547
|
+
orders_df = orders_df.with_columns(
|
|
548
|
+
pl.col("avgprc").cast(pl.Float64).alias("average_price")
|
|
549
|
+
)
|
|
550
|
+
if "remarks" not in orders_df.columns:
|
|
551
|
+
orders_df = orders_df.with_columns(pl.lit(None).alias("tag"))
|
|
552
|
+
else:
|
|
553
|
+
orders_df = orders_df.with_columns(
|
|
554
|
+
pl.col("remarks").cast(pl.String).alias("tag")
|
|
555
|
+
)
|
|
541
556
|
if "trigger_price" not in orders_df.columns:
|
|
542
557
|
orders_df = orders_df.with_columns(pl.lit(None).alias("trigger_price"))
|
|
543
558
|
if "average_price" not in orders_df.columns:
|
|
@@ -354,7 +354,8 @@ class Upstox(Broker):
|
|
|
354
354
|
# Get Positions
|
|
355
355
|
api_response = api_instance.get_positions(self.api_version)
|
|
356
356
|
positions = [
|
|
357
|
-
position.to_dict()
|
|
357
|
+
position.to_dict()
|
|
358
|
+
for position in api_response.data # type:ignore
|
|
358
359
|
]
|
|
359
360
|
positions_df = pl.DataFrame(positions)
|
|
360
361
|
except ApiException as e:
|
|
@@ -484,13 +485,6 @@ class Upstox(Broker):
|
|
|
484
485
|
if tag:
|
|
485
486
|
orders_df = orders_df.filter(pl.col("tag") == tag)
|
|
486
487
|
|
|
487
|
-
orders_df = orders_df.with_columns(
|
|
488
|
-
pl.col("instrument_token")
|
|
489
|
-
.str.split_exact("|", 1)
|
|
490
|
-
.struct.rename_fields(["upstox_exchange", "token"])
|
|
491
|
-
.alias("fields")
|
|
492
|
-
).unnest("fields")
|
|
493
|
-
|
|
494
488
|
orders_df = orders_df.with_columns(
|
|
495
489
|
pl.when(pl.col("exchange") == "NSE")
|
|
496
490
|
.then(pl.col("tradingsymbol").str.replace("-EQ", ""))
|
|
@@ -498,6 +492,17 @@ class Upstox(Broker):
|
|
|
498
492
|
.alias("tradingsymbol")
|
|
499
493
|
)
|
|
500
494
|
|
|
495
|
+
orders_df = orders_df.with_columns(
|
|
496
|
+
pl.struct(["exchange", "tradingsymbol"])
|
|
497
|
+
.map_elements(
|
|
498
|
+
lambda x: int(
|
|
499
|
+
self.symbol_attribute(x["exchange"], x["tradingsymbol"], "token")
|
|
500
|
+
),
|
|
501
|
+
return_dtype=pl.Int64,
|
|
502
|
+
)
|
|
503
|
+
.alias("token")
|
|
504
|
+
)
|
|
505
|
+
|
|
501
506
|
orders_df = orders_df.with_columns(
|
|
502
507
|
pl.col("order_timestamp")
|
|
503
508
|
.str.strptime(pl.Datetime, "%Y-%m-%d %H:%M:%S")
|
|
File without changes
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
from quantplay.service import market
|
|
2
|
+
import pandas as pd
|
|
3
|
+
import time
|
|
4
|
+
from quantplay.broker.client import broker_client
|
|
5
|
+
|
|
6
|
+
backtest_date = "2022-01-20"
|
|
7
|
+
|
|
8
|
+
def load_data(data_date):
|
|
9
|
+
# Load data
|
|
10
|
+
data = market.data(interval="minute", symbols_by_security_type={"EQ": ["NIFTY BANK"]})
|
|
11
|
+
data = data[data.date > "{} 08:15:00".format(data_date)]
|
|
12
|
+
data = data[data.date < "{} 15:15:00".format(data_date)]
|
|
13
|
+
data.loc[:, "day_of_week"] = data.date.dt.day_name()
|
|
14
|
+
data = data[data.date.dt.hour < 17]
|
|
15
|
+
|
|
16
|
+
# Add additional attributes
|
|
17
|
+
data = market.add_expiry(data, security_type="OPT", days_offset=0)
|
|
18
|
+
|
|
19
|
+
return data
|
|
20
|
+
|
|
21
|
+
data = load_data(backtest_date)
|
|
22
|
+
|
|
23
|
+
data_seq = data.to_dict('records')
|
|
24
|
+
|
|
25
|
+
for d in data_seq:
|
|
26
|
+
timestamp = d['date']
|
|
27
|
+
broker_client.ping(timestamp)
|
|
28
|
+
ltp = d['open']
|
|
29
|
+
strike_gap = d['strike_gap']
|
|
30
|
+
expiry = d['expiry_date']
|
|
31
|
+
if timestamp.hour == 9 and timestamp.minute < 30:
|
|
32
|
+
print("waiting for market to cool down")
|
|
33
|
+
continue
|
|
34
|
+
|
|
35
|
+
if timestamp.hour > 13:
|
|
36
|
+
print("market is about to close, let's not place any orders")
|
|
37
|
+
continue
|
|
38
|
+
|
|
39
|
+
orders = broker_client.orders(tag="ladder")
|
|
40
|
+
|
|
41
|
+
if len(orders) == 0:
|
|
42
|
+
atm = int(round(ltp / strike_gap) * strike_gap)
|
|
43
|
+
pe_symbol = broker_client.option_symbol("NIFTY BANK", expiry, atm, "PE")
|
|
44
|
+
ce_symbol = broker_client.option_symbol("NIFTY BANK", expiry, atm, "CE")
|
|
45
|
+
|
|
46
|
+
broker_client.execute_order(
|
|
47
|
+
tradingsymbol=pe_symbol,
|
|
48
|
+
exchange="NSE",
|
|
49
|
+
quantity=100,
|
|
50
|
+
order_type='MARKET',
|
|
51
|
+
transaction_type='SELL',
|
|
52
|
+
stoploss=0.8,
|
|
53
|
+
tag="ladder",
|
|
54
|
+
product="NRML"
|
|
55
|
+
)
|
|
56
|
+
broker_client.execute_order(
|
|
57
|
+
tradingsymbol=ce_symbol,
|
|
58
|
+
exchange="NSE",
|
|
59
|
+
quantity=100,
|
|
60
|
+
order_type='MARKET',
|
|
61
|
+
transaction_type='SELL',
|
|
62
|
+
stoploss=0.8,
|
|
63
|
+
tag="ladder",
|
|
64
|
+
product="NRML"
|
|
65
|
+
)
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
from quantplay.strategy.base import QuantplayAlgorithm
|
|
2
|
+
from quantplay.utils.constant import TickInterval
|
|
3
|
+
from quantplay.service import market
|
|
4
|
+
from quantplay.order_execution.mean_price import MeanPriceExecutionAlgo
|
|
5
|
+
import numpy as np
|
|
6
|
+
import pandas as pd
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Musk(QuantplayAlgorithm):
|
|
10
|
+
def __init__(self):
|
|
11
|
+
|
|
12
|
+
# Mandatory Attributes
|
|
13
|
+
self.interval = TickInterval.minute
|
|
14
|
+
self.entry_time = "09:29"
|
|
15
|
+
self.exit_time = "15:15"
|
|
16
|
+
self.strategy_trigger_times = [self.entry_time]
|
|
17
|
+
self.exchange_to_trade_on = "NFO"
|
|
18
|
+
self.option_nearest_expiry_offset = 0
|
|
19
|
+
self.option_chain_depth = 0
|
|
20
|
+
self.backtest_after_date = "2021-01-01"
|
|
21
|
+
self.backtest_before_date = "2022-02-25"
|
|
22
|
+
self.stream_symbols_by_security_type = {"EQ": ["NIFTY BANK"]}
|
|
23
|
+
self.columns_for_uuid = ["date", "symbol"]
|
|
24
|
+
self.exact_number_of_orders_per_uuid = 2
|
|
25
|
+
self.strategy_type = "intraday"
|
|
26
|
+
self.strategy_tag = "musk"
|
|
27
|
+
self.execution_algo = MeanPriceExecutionAlgo(7)
|
|
28
|
+
|
|
29
|
+
self.data_required_for_days = 20
|
|
30
|
+
|
|
31
|
+
super(Musk, self).__init__()
|
|
32
|
+
|
|
33
|
+
def get_trades(self, market_data):
|
|
34
|
+
equity_data = market_data[(market_data.security_type == "EQ") & (market_data.symbol != "SBIN")]
|
|
35
|
+
|
|
36
|
+
unique_equity_symbols = list(equity_data.symbol.unique())
|
|
37
|
+
assert len(unique_equity_symbols) == 2
|
|
38
|
+
assert set(unique_equity_symbols) == {"NIFTY 50", "NIFTY BANK"}
|
|
39
|
+
|
|
40
|
+
trades = market.get_trades(equity_data, self.entry_time)
|
|
41
|
+
|
|
42
|
+
trades = self.add_expiry(trades, security_type="OPT")
|
|
43
|
+
trades.to_csv("/tmp/{}.csv".format(self.strategy_tag))
|
|
44
|
+
trades = trades[trades.date.dt.year >= 2019]
|
|
45
|
+
|
|
46
|
+
trades = trades[trades.strike_gap > 0]
|
|
47
|
+
trades.loc[:, "atm_price"] = (
|
|
48
|
+
round(trades.close / trades.strike_gap) * trades.strike_gap
|
|
49
|
+
)
|
|
50
|
+
trades.loc[:, "atm_price"] = trades.atm_price.astype(int)
|
|
51
|
+
|
|
52
|
+
pe_trades = market.option_symbol(
|
|
53
|
+
trades, price_column="atm_price", option_type="PE"
|
|
54
|
+
)
|
|
55
|
+
ce_trades = market.option_symbol(
|
|
56
|
+
trades, price_column="atm_price", option_type="CE"
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
trades = pd.concat([pe_trades, ce_trades])
|
|
60
|
+
|
|
61
|
+
trades.loc[:, "day_of_week"] = trades.date.dt.day_name()
|
|
62
|
+
trades = trades[trades.day_of_week.isin(["Monday", "Tuesday", "Wednesday", "Thursday"])]
|
|
63
|
+
|
|
64
|
+
trades.loc[:, "transaction_type"] = "SELL"
|
|
65
|
+
trades.loc[:, "stoploss"] = np.where(trades.symbol == "NIFTY 50", 0.5, 0.8)
|
|
66
|
+
trades.loc[:, "quantity"] = np.where(trades.symbol == "NIFTY 50", 100, 50)
|
|
67
|
+
|
|
68
|
+
trades = self.filter_uuids_not_matching_count(trades)
|
|
69
|
+
|
|
70
|
+
return trades
|
|
71
|
+
|
|
72
|
+
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -42,6 +42,17 @@ quantplay/model/__init__.py
|
|
|
42
42
|
quantplay/model/broker.py
|
|
43
43
|
quantplay/model/generics.py
|
|
44
44
|
quantplay/model/order_event.py
|
|
45
|
+
quantplay/strategies/__init__.py
|
|
46
|
+
quantplay/strategies/equities/__init__.py
|
|
47
|
+
quantplay/strategies/equities/intraday/__init__.py
|
|
48
|
+
quantplay/strategies/equities/overnight/__init__.py
|
|
49
|
+
quantplay/strategies/futures/__init__.py
|
|
50
|
+
quantplay/strategies/futures/overnight/__init__.py
|
|
51
|
+
quantplay/strategies/options/__init__.py
|
|
52
|
+
quantplay/strategies/options/intraday/__init__.py
|
|
53
|
+
quantplay/strategies/options/intraday/ladder.py
|
|
54
|
+
quantplay/strategies/options/intraday/musk.py
|
|
55
|
+
quantplay/strategies/options/intraday/short_straddle.py
|
|
45
56
|
quantplay/utils/__init__.py
|
|
46
57
|
quantplay/utils/constant.py
|
|
47
58
|
quantplay/utils/exchange.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{quantplay-2.0.22/quantplay/wrapper → quantplay-2.0.24/quantplay/strategies/equities}/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{quantplay-2.0.22/tests → quantplay-2.0.24/quantplay/strategies/equities/overnight}/__init__.py
RENAMED
|
File without changes
|
{quantplay-2.0.22/tests/wrapper → quantplay-2.0.24/quantplay/strategies/futures}/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
/quantplay-2.0.22/tests/conftest.py → /quantplay-2.0.24/quantplay/strategies/options/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|