Shoonya::placeOrder()   B
last analyzed

Complexity

Conditions 6
Paths 18

Size

Total Lines 46
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 4 Features 0
Metric Value
cc 6
eloc 29
c 5
b 4
f 0
nc 18
nop 15
dl 0
loc 46
rs 8.8337

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
namespace Core\Api;
4
5
use GuzzleHttp\Client;
6
use Katzgrau\KLogger\Logger;
7
8
class Shoonya {
9
10
    protected $guzzle, $jKey, $userName, $accountId, $pwd, $uid,$exarr,$brkname,$email;
11
    protected $cred,$logger,$orderNo = [];
12
    protected const Delivery = 'C', Intraday = 'I', Normal = 'M', CF = 'M';
13
    protected const FeedTouchLine = 1,FeedSnapQuoate=2;
14
    protected const PriceMarket = 'MKT', PriceLimit = 'LMT', PrinceSLLmit = 'SL-LMT', PriceSLM = 'SL-MKT';
15
    Protected const Buy = 'B', Sell = 'S';
16
    
17
    protected $urls = [
18
        'host' => 'https://shoonyatrade.finvasia.com/',
19
        'websocket_endpoint' => 'wss://shoonyatrade.finvasia.com/NorenWSTP',
20
        'endpoint' => 'https://shoonyatrade.finvasia.com/NorenWClientTP',
21
        "eodhost" => 'https://shoonya.finvasia.com/chartApi/getdata',
22
    ];
23
    protected $routes = [
24
        'login' => '/QuickAuth',
25
        'logout' => '/Logout',
26
        'forgot_password' => '/ForgotPassword',
27
        'change_password' => '/Changepwd',
28
        'watchlist_names' => '/MWList',
29
        'watchlist' => '/MarketWatch',
30
        'watchlist_add' => '/AddMultiScripsToMW',
31
        'watchlist_delete' => '/DeleteMultiMWScrips',
32
        'placeorder' => '/PlaceOrder',
33
        'modifyorder' => '/ModifyOrder',
34
        'cancelorder' => '/CancelOrder',
35
        'exitorder' => '/ExitSNOOrder',
36
        'product_conversion' => '/ProductConversion',
37
        'orderbook' => '/OrderBook',
38
        'tradebook' => '/TradeBook',
39
        'singleorderhistory' => '/SingleOrdHist',
40
        'searchscrip' => '/SearchScrip',
41
        'TPSeries' => '/TPSeries',
42
        'optionchain' => '/GetOptionChain',
43
        'holdings' => '/Holdings',
44
        'limits' => '/Limits',
45
        'positions' => '/PositionBook',
46
        'scripinfo' => '/GetSecurityInfo',
47
        'getquotes' => '/GetQuotes',
48
    ];
49
50
    public function __construct() {
51
        $this->cred = parse_ini_file('cred.ini');
52
        $this->guzzle = new Client();
53
        $this->logger = new Logger('log/');
54
    }
55
    
56
    /**
57
     * 
58
     * @return bool
59
     */
60
    public function login():bool {
61
        $this->cred['pwd'] = hash('sha256', utf8_encode($this->cred['pwd']));
62
        $this->cred['appkey'] = hash('sha256', utf8_encode($this->cred['uid'] . '|' . $this->cred['appkey']));
63
        $req = $this->request('login', $this->cred, false);
64
        if($this->log($req, ['logged in successfully!','falied to loggedin!'])){
65
            $this->sessionData($req);
66
            return true;
67
        }
68
        return false;
69
    }
70
71
    /**
72
     * 
73
     * @return bool
74
     */
75
    public function logout() :bool {
76
        $req = $this->request('logout', ['ordersource' => 'API', 'uid' => $this->uid]);
77
        if($this->log($req, ['logout successfully!','failed to logout!'])){
78
            $this->jKey = null;
79
            $this->userName = null;
80
            $this->accountId = null;
81
            $this->uid = null;
82
            return true;
83
        }
84
        return false;
85
    }
86
    
87
    /**
88
     * 
89
     * @param string $uid
90
     * @param string $pan
91
     * @param string $dob
92
     * @return bool
93
     */
94
    public function forgotPassword(string $uid, string $pan, string $dob):bool {
95
        $values = [
96
            'source'=>'API',
97
            'uid' => $uid,
98
            'pan' => $pan,
99
            'dob' => $dob
100
        ];
101
        $req = $this->request('forgot_password', $values,false);
102
        return $this->log($req, ['Password Changed Successfully','Could not changed password!']);   
103
    }
104
    
105
    /**
106
     * 
107
     * @param string $searchtext
108
     * @param string $exchange
109
     * @return array
110
     */
111
    public function searchScrip(string $searchtext, string $exchange ='BSE'):array {
112
        $values = [
113
            'uid' => $this->uid,
114
            'exch' => $exchange,
115
            'stext' => $searchtext // urllib . parse . quote_plus
116
        ];
117
        return $this->request('searchscrip', $values)->values;
118
    }
119
    
120
    /**
121
     * 
122
     * @param string $prd
123
     * @param string $seg
124
     * @param string $exch
125
     * @return type
0 ignored issues
show
Bug introduced by
The type Core\Api\type was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
126
     */
127
    public function getLimits($prd=null,$seg=null,$exch=null) {
128
        $values = [
129
            'uid' => $this->uid,
130
            'actid' => $this->accountId
131
        ];
132
        
133
        if(!is_null($prd)){
134
            $values['prd'] = $prd;
135
        }
136
        if(!is_null($seg)) {
137
            $values['seg'] = $seg;
138
        }
139
        if(!is_null($exch)){
140
            $values['exch'] = $exch;
141
        }
142
        return $this->request('limits', $values);
143
    }
144
    
145
    public function getOptionChain(string $tsym, int $strprc,int $count=5, string $exch='NFO') {
146
        $values = [
147
            'uid'=> $this->uid,
148
            'exch'=>$exch,
149
            'tsym' =>$tsym,
150
            'strprc' => "$strprc",
151
            'cnt'=> "$count"
152
        ];
153
        return $this->request('optionchain', $values);
154
    }
155
    
156
    /**
157
     * 
158
     * @param string $token
159
     * @param string $exch
160
     */
161
    public function getScripInfo(string $token,string $exch='BSE') {
162
        $tkNum = parse_ini_file('scrip/bse.ini');
163
        $values = [
164
            'uid'=> $this->uid,
165
            'exch'=>$exch,
166
            'token'=>$tkNum[$token]
167
        ];
168
        return $this->request('scripinfo', $values);
169
    }
170
    
171
    /**
172
     * 
173
     * @param string $token
174
     * @param string $exchange
175
     * @return array
176
     */
177
    public function getQuotes(string $token, string $exchange ='BSE' ){
178
        $tkNum = parse_ini_file('scrip/bse.ini');
179
        $values = [
180
            'uid'=> $this->accountId,
181
            'exch'=>$exchange,
182
            'token'=>$tkNum[$token]
183
        ];
184
        return $this->request('getquotes', $values);
185
    }
186
    
187
    /**
188
     * 
189
     * @param string $token
190
     * @param string $startTime d-m-Y
191
     * @param string $endTime
192
     * @param string $interval 1, 3, 5 , 10, 15, 30, 60, 120, 240
193
     * @param string $exch
194
     */
195
    public function getTimePriceSeries(string $token,string $startTime = null, string $endTime=null, string $interval='15', string $exch='BSE') {
196
        $tkNum = parse_ini_file('scrip/bse.ini');
197
        if(is_null($startTime)) {
198
            $startTime = (string)strtotime(date('d-m-Y'));
199
        }
200
        else{
201
            $startTime = (string)strtotime($startTime);
202
        }
203
        
204
        $values = [
205
            'uid'=> $this->accountId,
206
            'exch'=>$exch,
207
            'token'=>$tkNum[$token],
208
            'st'=> $startTime
209
        ];
210
        if(!is_null($endTime)) {
211
            $values['et'] = (string)strtotime($endTime);
212
        }
213
        if(!is_null($interval)) {
0 ignored issues
show
introduced by
The condition is_null($interval) is always false.
Loading history...
214
            $values['intrv'] = (string) $interval;
215
        }
216
        return $this->request('TPSeries', $values);
217
    }
218
    
219
    /**
220
     * 
221
     * @param string $token
222
     * @param string $startDate
223
     * @param string $endDate
224
     * @param string $exch
225
     * @return type
226
     */
227
    public function getDailyPriceSeries(string $token,string $startDate, string $endDate=null, string $exch='BSE') {
228
        $tkNum = parse_ini_file('scrip/bse.ini');
229
        if(is_null($endDate)) {
230
            $et = (string) strtotime(date('d-m-Y'));
231
        }else {
232
            $et=  (string) strtotime($endDate);
233
        }
234
        $st = (string) strtotime($startDate);
235
        
236
        $values = [
237
            'uid'=> $this->accountId,
238
            'sym'=>" $exch : $tkNum[$token]" ,
239
            'from'=>$st,
240
            'to'=> $et
241
        ];
242
        $request = $this->guzzle->post($this->urls['eodhost'], [
243
                    'header' => ['Content-Type' =>  'application/json'],
244
                    'body' => $this->jData($values)
245
        ]);
246
        $decode = $this->decode($request->getBody());
247
        return $decode;
248
    }
249
    
250
    public function positionProductConversion() {
251
        
252
    }
253
    
254
    /**
255
     * 
256
     * @param int $orderNo
257
     * @return type
258
     */
259
    public function singleOrderHistory(int $orderNo) {
260
        return $this->request('singleorderhistory', ['uid'=> $this->uid,'norenordno'=>$orderNo]);
261
    }
262
263
    /**
264
     * 
265
     * @return array
266
     */
267
    public function getOrderbook() {
268
        return $this->request('orderbook', ['uid' => $this->uid]);
269
    }
270
    
271
    /**
272
     * 
273
     * @return type
274
     */
275
    public function getTradebook() {
276
        return $this->request('tradebook', ['uid' => $this->uid,'actid'=> $this->accountId]);
277
    }
278
279
    /**
280
     * 
281
     * @param string $productType
282
     * @return array | stdClass
0 ignored issues
show
Bug introduced by
The type Core\Api\stdClass was not found. Did you mean stdClass? If so, make sure to prefix the type with \.
Loading history...
283
     */
284
    public function getHoldings($productType = self::Delivery) {
285
        return $this->request('holdings', ['uid' => $this->uid,'actid' => $this->accountId,'prd' => $productType]);
286
    }
287
    
288
    /**
289
     * 
290
     * @return array | stdClass
291
     */
292
    public function getPositions() {
293
        return $this->request('positions',['uid' => $this->uid, 'actid' => $this->accountId]);
294
    }
295
296
    public function placeOrder($buy_or_sell, $productType, $exchange, $tradingSymbol, $quantity, $discloseQty,
297
            $priceType, $price = 0.0, $triggerPrice = null, $retention = 'DAY', $amo = 'NO', $remarks = null,
298
            $booklossPrice = 0.0, $bookprofitPrice = 0.0, $trailPrice = 0.0) {
299
300
        #prepare the data
301
        $values = ['ordersource' => 'API',
302
            'uid' => $this->uid,
303
            'actid' => $this->accountId,
304
            'trantype' => $buy_or_sell,
305
            'prd' => $productType,
306
            'exch' => $exchange,
307
            'tsym' => ($tradingSymbol), //urllib . parse . quote_plus
308
            'qty' => (string)($quantity),
309
            'dscqty' => (string)($discloseQty),
310
            'prctyp' => $priceType,
311
            'prc' => (string)($price),
312
            'trgprc' => (string)($triggerPrice),
313
            'ret' => $retention,
314
            'remarks' => $remarks,
315
            'amo' => $amo
316
        ];
317
318
        #if cover order or high leverage order
319
        if ($productType == 'H') {
320
            $values["blprc"] = (string)($booklossPrice);
321
            #trailing price
322
            if ($trailPrice != 0.0) {
323
                $values["trailprc"] = (string)($trailPrice);
324
            }
325
        }
326
327
        #bracket order
328
        if ($productType == 'B') {
329
            $values["blprc"] = (string)($booklossPrice);
330
            $values["bpprc"] = (string)($bookprofitPrice);
331
            #trailing price
332
            if ($trailPrice != 0.0) {
333
                $values["trailprc"] = (string)($trailPrice);
334
            }
335
        }
336
        $req = $this->request('placeorder', $values);
337
        if($this->log($req, ["order placed, ON:- $req->norenordno", 'failed to place order!'])) {
338
            $this->orderNo[] = $req->norenordno;
339
            return true;
340
        }
341
        return false;
342
    }
343
    
344
    public function getSessionData() {
345
        return ['jKey' => $this->jKey,'uid'=>$this->uid,'actid'=> $this->accountId, 'uname'=>$this->userName, $this->exarr, $this->brkname];
346
    }
347
    
348
    protected function sessionData($data) {
349
        $this->jKey = $data->susertoken;
350
        $this->userName = $data->uname;
351
        $this->accountId = $data->actid;
352
        $this->uid = $data->actid;
353
        $this->exarr = $data->exarr;
354
        $this->brkname = $data->brkname;
355
        $this->email = $data->email;
356
    }
357
358
    protected function decode($jsonData) {
359
        return json_decode($jsonData);
360
    }
361
    
362
    /**
363
     * 
364
     * @param object $req
365
     * @param array $msg
366
     * @return boolean
367
     */
368
    protected function log($req,array $msg) {
369
        if($req->stat == 'Ok') {
370
            $this->logger->info("User {$this->cred['uid']} " . $msg[0]);
371
            return true;
372
        }
373
        $this->logger->notice("User {$this->cred['uid']} " . $msg[1]);
374
        return false ;
375
    }
376
377
378
    protected function request(string $routes, array $jData,$iskey=true){
379
        $request = $this->post($this->routes[$routes], $this->jData($jData),$iskey);
380
        $decode = $this->decode($request->getBody());
381
        return $decode;
382
    }
383
384
    protected function post($routes, $body, $contentType = 'application/json') {
385
        $url = $this->urls['endpoint'] . $routes;
386
        return $this->guzzle->post($url, [
387
                    'header' => ['Content-Type' => $contentType],
388
                    'body' => $body
389
        ]);
390
    }
391
392
    protected function jData($data,$isKey = true) {
393
        if($isKey){
394
            return 'jData=' .json_encode($data) . $this->jKey();
395
        }
396
        return 'jData=' . json_encode($data);
397
    }
398
399
    protected function jKey() {
400
        return '&jKey=' . $this->jKey;
401
    }
402
403
}
404