@tradelayerprotocol/tradelayer 1.9.1

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.
Files changed (249) hide show
  1. package/.claude/settings.local.json +13 -0
  2. package/.claude/skills/tl-algo/SKILL.md +255 -0
  3. package/.gitattributes +2 -0
  4. package/.github/workflows/publish.yaml +26 -0
  5. package/4mm.js +163 -0
  6. package/LICENSE +21 -0
  7. package/NPMSwapRefactor.zip +0 -0
  8. package/README.md +217 -0
  9. package/address.sh +26 -0
  10. package/algoAPI.js +581 -0
  11. package/analyzepsbt.js +92 -0
  12. package/apiEx.js +99 -0
  13. package/bb_hyperscalper.js +290 -0
  14. package/bbo_demo.js +111 -0
  15. package/buyer.js +622 -0
  16. package/client.js +50 -0
  17. package/createTxTest.js +26 -0
  18. package/createWallet.js +75 -0
  19. package/daytrader.js +531 -0
  20. package/decodeTest.js +69 -0
  21. package/fundingManager.js +144 -0
  22. package/index.js +4 -0
  23. package/listener.js +27 -0
  24. package/litecoreTxBuilder.js +1128 -0
  25. package/mmEx.js +356 -0
  26. package/networks.js +51 -0
  27. package/orderbook.js +200 -0
  28. package/package.json +34 -0
  29. package/perTradeQueue.js +36 -0
  30. package/projectsTLNPMTLNPM/package-lock.json +162 -0
  31. package/projectsTLNPMTLNPM/package.json +5 -0
  32. package/quick.js +32 -0
  33. package/quickFut.js +37 -0
  34. package/quickSell.js +37 -0
  35. package/relayerClient.js +117 -0
  36. package/run4mm.js +80 -0
  37. package/run_bbo_tracker.js +241 -0
  38. package/seller.js +443 -0
  39. package/session.js +45 -0
  40. package/setup-lin-ltc.sh +139 -0
  41. package/setup-lin.sh +203 -0
  42. package/setup-win-ltc.bat +108 -0
  43. package/setup-win.bat +167 -0
  44. package/spam_screamer_futures.js +222 -0
  45. package/tradelayer.js/.gitattributes +2 -0
  46. package/tradelayer.js/README.md +2 -0
  47. package/tradelayer.js/oldTests/activationTest.js +6 -0
  48. package/tradelayer.js/oldTests/base58.test.js +23 -0
  49. package/tradelayer.js/oldTests/base64Decode.test.js +16 -0
  50. package/tradelayer.js/oldTests/blocksRefactor.js +140 -0
  51. package/tradelayer.js/oldTests/checkVestBalance.js +25 -0
  52. package/tradelayer.js/oldTests/consensusHashProto.js +151 -0
  53. package/tradelayer.js/oldTests/contractOrderbook.js +243 -0
  54. package/tradelayer.js/oldTests/createPayload.js +0 -0
  55. package/tradelayer.js/oldTests/createTestnetAddr.js +43 -0
  56. package/tradelayer.js/oldTests/decode.js +205 -0
  57. package/tradelayer.js/oldTests/decodeTest.js +50 -0
  58. package/tradelayer.js/oldTests/displayTallyMap.js +19 -0
  59. package/tradelayer.js/oldTests/encodeDecode.js +340 -0
  60. package/tradelayer.js/oldTests/expressTest.js +29 -0
  61. package/tradelayer.js/oldTests/extractBlocksVanilla.js +214 -0
  62. package/tradelayer.js/oldTests/extractBlocksVanillaa.js +179 -0
  63. package/tradelayer.js/oldTests/extractPubkeyTest.js +60 -0
  64. package/tradelayer.js/oldTests/fillInputCacheProto.js +111 -0
  65. package/tradelayer.js/oldTests/getRawTxTest.js +22 -0
  66. package/tradelayer.js/oldTests/indexTest.js +26 -0
  67. package/tradelayer.js/oldTests/initTokensTest.js +32 -0
  68. package/tradelayer.js/oldTests/interfaceChild.js +129 -0
  69. package/tradelayer.js/oldTests/listenerChild.js +112 -0
  70. package/tradelayer.js/oldTests/opdecode.js +26 -0
  71. package/tradelayer.js/oldTests/options.js +79 -0
  72. package/tradelayer.js/oldTests/optxtest.js +116 -0
  73. package/tradelayer.js/oldTests/optxtest1.js +64 -0
  74. package/tradelayer.js/oldTests/oracle.test.js +32 -0
  75. package/tradelayer.js/oldTests/orderbook.test.js +36 -0
  76. package/tradelayer.js/oldTests/parsing.js +93 -0
  77. package/tradelayer.js/oldTests/payload.js +13 -0
  78. package/tradelayer.js/oldTests/persistenceUnitTest.js +23 -0
  79. package/tradelayer.js/oldTests/property.test.js +53 -0
  80. package/tradelayer.js/oldTests/propertyLevel.js +75 -0
  81. package/tradelayer.js/oldTests/propertyTest.js +32 -0
  82. package/tradelayer.js/oldTests/queryAddressTest.js +17 -0
  83. package/tradelayer.js/oldTests/salter.js +14 -0
  84. package/tradelayer.js/oldTests/tally.js +81 -0
  85. package/tradelayer.js/oldTests/tally.test.js +48 -0
  86. package/tradelayer.js/oldTests/tally2.js +124 -0
  87. package/tradelayer.js/oldTests/tally3.js +142 -0
  88. package/tradelayer.js/oldTests/tallyDiag.js +38 -0
  89. package/tradelayer.js/oldTests/testGetRaw.js +40 -0
  90. package/tradelayer.js/oldTests/testHexConvert.js +47 -0
  91. package/tradelayer.js/oldTests/testNewEncoding.js +96 -0
  92. package/tradelayer.js/oldTests/testNewEncoding2.js +113 -0
  93. package/tradelayer.js/oldTests/testNewEncoding3 +112 -0
  94. package/tradelayer.js/oldTests/testNewEncoding3.js +168 -0
  95. package/tradelayer.js/oldTests/testOPReturn.js +102 -0
  96. package/tradelayer.js/oldTests/testPayload.js +23 -0
  97. package/tradelayer.js/oldTests/testRaw.js +50 -0
  98. package/tradelayer.js/oldTests/testSendTooMuch.js +20 -0
  99. package/tradelayer.js/oldTests/testTxBuild +28 -0
  100. package/tradelayer.js/oldTests/testTxBuild.js +42 -0
  101. package/tradelayer.js/oldTests/tokenOrderbook.js +243 -0
  102. package/tradelayer.js/oldTests/txUtilsA.js +515 -0
  103. package/tradelayer.js/oldTests/validityUnitTest.js +53 -0
  104. package/tradelayer.js/oldTests/vaults.js +72 -0
  105. package/tradelayer.js/oldTests/volumeIndex.js +117 -0
  106. package/tradelayer.js/oldTests/volumeIndex2.js +88 -0
  107. package/tradelayer.js/output_base64.txt +1 -0
  108. package/tradelayer.js/package-lock.json +9967 -0
  109. package/tradelayer.js/package.json +61 -0
  110. package/tradelayer.js/server/index.js +88 -0
  111. package/tradelayer.js/server/litecoind.exe +0 -0
  112. package/tradelayer.js/src/activation.js +303 -0
  113. package/tradelayer.js/src/adjuster.js +77 -0
  114. package/tradelayer.js/src/amm.js +400 -0
  115. package/tradelayer.js/src/base256.js +55 -0
  116. package/tradelayer.js/src/base94.js +79 -0
  117. package/tradelayer.js/src/channels.js +1163 -0
  118. package/tradelayer.js/src/clearing.js +3109 -0
  119. package/tradelayer.js/src/clearlist.js +364 -0
  120. package/tradelayer.js/src/client.js +295 -0
  121. package/tradelayer.js/src/consensus.js +613 -0
  122. package/tradelayer.js/src/contractRegistry.js +964 -0
  123. package/tradelayer.js/src/db.js +89 -0
  124. package/tradelayer.js/src/init.js +24 -0
  125. package/tradelayer.js/src/insurance.js +347 -0
  126. package/tradelayer.js/src/interface.js +218 -0
  127. package/tradelayer.js/src/interfaceExpress.js +178 -0
  128. package/tradelayer.js/src/iou.js +509 -0
  129. package/tradelayer.js/src/listener.js +226 -0
  130. package/tradelayer.js/src/logic.js +1702 -0
  131. package/tradelayer.js/src/main.js +927 -0
  132. package/tradelayer.js/src/marginMap.js +2165 -0
  133. package/tradelayer.js/src/options.js +126 -0
  134. package/tradelayer.js/src/oracle.js +394 -0
  135. package/tradelayer.js/src/orderbook.js +4123 -0
  136. package/tradelayer.js/src/persistence.js +554 -0
  137. package/tradelayer.js/src/property.js +411 -0
  138. package/tradelayer.js/src/reOrg.js +41 -0
  139. package/tradelayer.js/src/scaling.js +145 -0
  140. package/tradelayer.js/src/tally.js +1275 -0
  141. package/tradelayer.js/src/tradeHistoryManager.js +552 -0
  142. package/tradelayer.js/src/txDecoder.js +584 -0
  143. package/tradelayer.js/src/txEncoder.js +610 -0
  144. package/tradelayer.js/src/txIndex.js +502 -0
  145. package/tradelayer.js/src/txUtils.js +1392 -0
  146. package/tradelayer.js/src/types.js +429 -0
  147. package/tradelayer.js/src/validity.js +3077 -0
  148. package/tradelayer.js/src/vaults.js +430 -0
  149. package/tradelayer.js/src/vesting.js +491 -0
  150. package/tradelayer.js/src/volumeIndex.js +618 -0
  151. package/tradelayer.js/src/walletInterface.js +220 -0
  152. package/tradelayer.js/src/walletListener.js +665 -0
  153. package/tradelayer.js/tests/256decode.js +82 -0
  154. package/tradelayer.js/tests/UTXOracle.js +205 -0
  155. package/tradelayer.js/tests/base94test.js +23 -0
  156. package/tradelayer.js/tests/cancelTxTest.js +62 -0
  157. package/tradelayer.js/tests/contractInterfaceTest.js +48 -0
  158. package/tradelayer.js/tests/decimalTest.js +65 -0
  159. package/tradelayer.js/tests/decoderTest.js +100 -0
  160. package/tradelayer.js/tests/deltaCount.js +47 -0
  161. package/tradelayer.js/tests/deltaCount2.js +60 -0
  162. package/tradelayer.js/tests/interfaceTest.js +37 -0
  163. package/tradelayer.js/tests/mainTest.js +53 -0
  164. package/tradelayer.js/tests/makeActivationTest.js +24 -0
  165. package/tradelayer.js/tests/maxHeightTest.js +49 -0
  166. package/tradelayer.js/tests/reverseHash.js +72 -0
  167. package/tradelayer.js/tests/sensitiveConsoleOutput.txt +267 -0
  168. package/tradelayer.js/tests/tallyTest.js +40 -0
  169. package/tradelayer.js/tests/testBuybacks.js +46 -0
  170. package/tradelayer.js/tests/testCodeHash.js +49 -0
  171. package/tradelayer.js/tests/testConsensusHash.js +91 -0
  172. package/tradelayer.js/tests/testDecode.js +30 -0
  173. package/tradelayer.js/tests/testEncodingLengths.js +129 -0
  174. package/tradelayer.js/tests/testGetTx +32 -0
  175. package/tradelayer.js/tests/testGetTx.js +32 -0
  176. package/tradelayer.js/tests/testHexHash.js +32 -0
  177. package/tradelayer.js/tests/testIndexHash.js +35 -0
  178. package/tradelayer.js/tests/testInitContracts.js +38 -0
  179. package/tradelayer.js/tests/testMaxConsensus.js +12 -0
  180. package/tradelayer.js/tests/testMaxSynth.js +44 -0
  181. package/tradelayer.js/tests/testMint.js +21 -0
  182. package/tradelayer.js/tests/testNetwork.js +33 -0
  183. package/tradelayer.js/tests/testOrderbookLoad.js +62 -0
  184. package/tradelayer.js/tests/testRebates.js +32 -0
  185. package/tradelayer.js/tests/testRedeem.js +22 -0
  186. package/tradelayer.js/tests/testTokenTrade.js +39 -0
  187. package/tradelayer.js/tests/testTxBuild.js +42 -0
  188. package/tradelayer.js/tests/testUTXOTrade.js +27 -0
  189. package/tradelayer.js/tests/tokenTradeHistory.js +27 -0
  190. package/tradelayer.js/tests/tradeFutures.js +40 -0
  191. package/tradelayer.js/tests/tradeHistoryExample.js +35 -0
  192. package/tradelayer.js/tests/tradeHistoryLoad.js +15 -0
  193. package/tradelayer.js/tests/txScanTest.js +134 -0
  194. package/tradelayer.js/tests/validateTest.js +136 -0
  195. package/tradelayer.js/tests/vestingTest.js +37 -0
  196. package/tradelayer.js/utils/activateMainnet.js +59 -0
  197. package/tradelayer.js/utils/activateMainnetDoge.js +63 -0
  198. package/tradelayer.js/utils/autocompactdb.js +23 -0
  199. package/tradelayer.js/utils/base64toHex.js +32 -0
  200. package/tradelayer.js/utils/broadcastDoge.js +38 -0
  201. package/tradelayer.js/utils/calcRedeem.js +19 -0
  202. package/tradelayer.js/utils/checkNetwork.js +27 -0
  203. package/tradelayer.js/utils/createAddress.js +48 -0
  204. package/tradelayer.js/utils/createAttestation.js +133 -0
  205. package/tradelayer.js/utils/createContract.js +118 -0
  206. package/tradelayer.js/utils/createOracle.js +94 -0
  207. package/tradelayer.js/utils/createwallet.js +20 -0
  208. package/tradelayer.js/utils/crossFuturesTrades.js +57 -0
  209. package/tradelayer.js/utils/crossTokenTrades.js +62 -0
  210. package/tradelayer.js/utils/dumpPriv.js +29 -0
  211. package/tradelayer.js/utils/generateChannel.js +34 -0
  212. package/tradelayer.js/utils/getInfo.js +21 -0
  213. package/tradelayer.js/utils/hardWipe.js +20 -0
  214. package/tradelayer.js/utils/hexTo64.js +16 -0
  215. package/tradelayer.js/utils/importAddress.js +28 -0
  216. package/tradelayer.js/utils/importpriv.js +20 -0
  217. package/tradelayer.js/utils/issueOracleContract.js +67 -0
  218. package/tradelayer.js/utils/issueTokens.js +41 -0
  219. package/tradelayer.js/utils/listunspent.js +66 -0
  220. package/tradelayer.js/utils/litecoinClient.js +30 -0
  221. package/tradelayer.js/utils/loadwallet.js +20 -0
  222. package/tradelayer.js/utils/publishOracle.js +113 -0
  223. package/tradelayer.js/utils/sendActivation.js +21 -0
  224. package/tradelayer.js/utils/sendChannelContractTrade.js +34 -0
  225. package/tradelayer.js/utils/sendChannelTokenTrade.js +34 -0
  226. package/tradelayer.js/utils/sendCommit.js +24 -0
  227. package/tradelayer.js/utils/sendDoge.js +62 -0
  228. package/tradelayer.js/utils/sendDogeMain.js +67 -0
  229. package/tradelayer.js/utils/sendDogeTx.js +46 -0
  230. package/tradelayer.js/utils/sendLTC.js +63 -0
  231. package/tradelayer.js/utils/sendMainnet.js +62 -0
  232. package/tradelayer.js/utils/sendTransfer.js +19 -0
  233. package/tradelayer.js/utils/sendVestTest.js +88 -0
  234. package/tradelayer.js/utils/sendWithdrawal.js +26 -0
  235. package/tradelayer.js/utils/simpleStart.js +8 -0
  236. package/tradelayer.js/utils/startStop.js +27 -0
  237. package/tradelayer.js/utils/structuredTrades.js +136 -0
  238. package/tradelayer.js/utils/verifySignature.js +90 -0
  239. package/tradelayer.js/utils/verifyWitnessAndScriptPubkey.js +41 -0
  240. package/tradelayer.js/utils/walletCache.js +172 -0
  241. package/tradelayer.js/utils/walletContractInterface.js +48 -0
  242. package/tradelayer.js/utils/walletFetchTxs.js +66 -0
  243. package/tradelayer.js/utils/walletUtils.js +97 -0
  244. package/tradelayer.js/utils/wipeDB.js +55 -0
  245. package/tradelayer.js/utils/wipeDBNotTx.js +50 -0
  246. package/txEncoder.js +529 -0
  247. package/utility.js +28 -0
  248. package/verifymessage.js +38 -0
  249. package/ws-transport.js +311 -0
@@ -0,0 +1,26 @@
1
+ const createclient = require('tradelayer/litecoinClient.js'); // Adjust the path if necessary
2
+
3
+ // Initialize the Litecoin client
4
+ const client = createclient(true); // Pass 'true' for testnet, 'false' for mainnet
5
+
6
+ // Promisify the necessary client functions
7
+ const createRawTransactionAsync = require('util').promisify(client.createRawTransaction.bind(client));
8
+
9
+ const testTransaction = async () => {
10
+ //try {
11
+ // Example JSON that can be pasted in, replace with your transaction details
12
+ const inputs = [{"txid":"3b4546ad93a7d77ee684ec1ae01ad7eb3f67183459cd41da92ed0f1940eba1f1","vout":0},{"txid":"bc395db7a7a11b42e9711e192a860da2fffe64955cae6dd673e267532f328b3d","vout":1}]
13
+ const outputs = [{"tltc1qvlwcnwlhnja7wlj685ptwxej75mms9nyv7vuy8":0.02920059},{"tltc1q89kkgaslk0lt8l90jkl3cgwg7dkkszn73u4d2t":0.0001},{"data":"746c33302c302e3030346e796d386571756170712c302c3770732c302c312c30"}]
14
+ // Call getRawTransaction with the provided parameters
15
+ const rawTx = await createRawTransactionAsync(inputs,outputs);
16
+
17
+ // Log the raw transaction result
18
+ console.log("Raw Transaction Result: ", rawTx);
19
+
20
+ //} catch (error) {
21
+ // console.error("Error fetching raw transaction:", error.message);
22
+ //}
23
+ };
24
+
25
+ // Run the test
26
+ testTransaction();
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Generates a new BIP39 seed phrase and derives a default address.
4
+ *
5
+ * Usage:
6
+ * node createWallet.js [network]
7
+ *
8
+ * Examples:
9
+ * node createWallet.js # defaults to LTCTEST
10
+ * node createWallet.js LTC
11
+ * node createWallet.js BTC
12
+ *
13
+ * BIP44 paths:
14
+ * LTC / LTCTEST : m/44'/2'/0'/0/0
15
+ * BTC / BTCTEST : m/44'/0'/0'/0/0
16
+ */
17
+
18
+ const nodeCrypto = require('crypto');
19
+ const bip39 = require('bip39');
20
+ const { BIP32Factory } = require('bip32');
21
+ const bitcoin = require('bitcoinjs-lib');
22
+ const ecc = require('tiny-secp256k1');
23
+ const { ECPairFactory } = require('ecpair');
24
+ const networks = require('./networks');
25
+
26
+ const ECPair = ECPairFactory(ecc);
27
+ const bip32 = BIP32Factory(ecc);
28
+ bitcoin.initEccLib(ecc);
29
+
30
+ const networkPaths = {
31
+ LTC: "m/84'/2'/0'/0",
32
+ LTCTEST: "m/84'/1'/0'/0",
33
+ BTC: "m/84'/0'/0'/0",
34
+ BTCTEST: "m/84'/1'/0'/0",
35
+ };
36
+
37
+ const networkName = (process.argv[2] || 'LTCTEST').toUpperCase();
38
+ const net = networks[networkName];
39
+ const basePath = networkPaths[networkName];
40
+ if (!net || !basePath) {
41
+ console.error(`Unknown network "${networkName}". Choose from: ${Object.keys(networkPaths).join(', ')}`);
42
+ process.exit(1);
43
+ }
44
+
45
+ const derivePath = `${basePath}/0`;
46
+ const mnemonic = bip39.generateMnemonic(256);
47
+ const seed = bip39.mnemonicToSeedSync(mnemonic);
48
+ const root = bip32.fromSeed(seed, net);
49
+ const child = root.derivePath(derivePath);
50
+
51
+ const { address } = bitcoin.payments.p2wpkh({
52
+ pubkey: Buffer.from(child.publicKey),
53
+ network: net,
54
+ });
55
+
56
+ const pubkey = Buffer.from(child.publicKey).toString('hex');
57
+
58
+ console.log('');
59
+ console.log('=== NEW WALLET ===');
60
+ console.log('');
61
+ console.log(`Network : ${networkName}`);
62
+ console.log(`Path : ${derivePath}`);
63
+ console.log('');
64
+ console.log('SEED PHRASE (write this down, do NOT share):');
65
+ console.log('');
66
+ console.log(` ${mnemonic}`);
67
+ console.log('');
68
+ console.log(`Address : ${address}`);
69
+ console.log(`PubKey : ${pubkey}`);
70
+ console.log('');
71
+ console.log('Fund this address, then start the API:');
72
+ console.log('');
73
+ console.log(` const ApiWrapper = require('./algoAPI');`);
74
+ console.log(` const api = new ApiWrapper(obURL, obPort, ${networkName.includes('TEST')}, true, '${address}', '${pubkey}', '${networkName}');`);
75
+ console.log('');
package/daytrader.js ADDED
@@ -0,0 +1,531 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * fib_sma_taker_tl.js
5
+ *
6
+ * TL-style ETF taker algo:
7
+ * - Signals + PnL from Alpaca ETF bars (SPY by default)
8
+ * - Executes ETF synth on TradeLayer via ApiWrapper
9
+ * - Optional hedge with Alpaca options (nearest strike put/call)
10
+ * - Fibonacci SMA ladder: 13, 21, 34, 55, 89, 144
11
+ * * We look for stacked triples like [55, 89, 144]:
12
+ * uptrend: SMA13 > SMA21 > ... > SMA144
13
+ * downtrend: SMA13 < SMA21 < ... < SMA144
14
+ * * For each triple [pShort, pMid, pLong], if stacked:
15
+ * - uptrend: SMA(pShort) > SMA(pMid) > SMA(pLong)
16
+ * - downtrend: SMA(pShort) < SMA(pMid) < SMA(pLong)
17
+ * we pick the triple with the *largest* pLong and enter
18
+ * on retrace to SMA(pShort) (“next one when the longer ones
19
+ * are above each other”).
20
+ *
21
+ * - Trailing stop using last 5 bars once PnL >= 10 bps
22
+ * - Hard stop -20 bps if no hedge
23
+ *
24
+ * This is example code. Backtest before real money.
25
+ */
26
+
27
+ const Alpaca = require('@alpacahq/alpaca-trade-api');
28
+ const axios = require('axios');
29
+
30
+ // ===== TL ApiWrapper (wire this to match run_bbo_tracker) =====
31
+ /**
32
+ * Adjust this import/path to match however run_bbo_tracker.js pulls ApiWrapper.
33
+ * If that file does something like:
34
+ * const { ApiWrapper } = require('./algoAPI');
35
+ * then keep this exactly the same.
36
+ */
37
+ const { ApiWrapper } = require('./algoAPI'); // <--- CHECK THIS PATH
38
+
39
+ // Example env-driven TL config; mirror whatever you use in quick_env / BBO tracker.
40
+ const tlApi = new ApiWrapper(
41
+ process.env.TL_BASE_URL || 'http://127.0.0.1',
42
+ Number(process.env.TL_PORT || 3001),
43
+ process.env.TL_TEST === 'true',
44
+ process.env.TL_ALREADY_ON === 'true',
45
+ process.env.TL_ADDRESS,
46
+ process.env.TL_PUBKEY,
47
+ process.env.TL_NETWORK || 'LTCTEST'
48
+ );
49
+
50
+ // ===== Global state for TL position tracking =====
51
+ /**
52
+ * We track TL position in-process instead of querying the node:
53
+ * currentPosition = {
54
+ * side: 'long' | 'short',
55
+ * qty: number,
56
+ * entryPrice: number // from Alpaca ETF price at entry
57
+ * }
58
+ */
59
+ let currentPosition = null;
60
+ let currentHedgeSymbol = null;
61
+
62
+ // ===== Config =====
63
+ const CFG = {
64
+ // Alpaca ETF (price + bars + hedge)
65
+ ETF_SYMBOL: 'SPY', // Underlying ETF on Alpaca
66
+ BAR_TIMEFRAME: '1Min', // Alpaca bars: 1Min, 5Min, 15Min, etc.
67
+ BAR_LOOKBACK_DAYS: 3,
68
+ BAR_LIMIT: 800,
69
+
70
+ // TL market symbol for ETF synth (whatever you use on TradeLayer)
71
+ TL_MARKET: 'SPY-PERP', // TODO: adjust to your TL symbol
72
+
73
+ // Fibonacci SMA ladder
74
+ FIB_PERIODS: [13, 21, 34, 55, 89, 144],
75
+ // Triples we consider for trend; we’ll pick the one with largest max period
76
+ FIB_TRIPLES: [
77
+ [13, 21, 34],
78
+ [21, 34, 55],
79
+ [34, 55, 89],
80
+ [55, 89, 144],
81
+ ],
82
+
83
+ USE_OPTION_HEDGE: true,
84
+ HEDGE_MIN_DTE: 3,
85
+ HEDGE_MAX_DTE: 30,
86
+
87
+ BASE_NOTIONAL_USD: 5_000, // per trade (notional on ETF synth)
88
+ PROFIT_TRAIL_TRIGGER_BPS: 10, // start trailing at +10 bps
89
+ DEFAULT_STOP_BPS: 20, // hard stop at -20 bps when unhedged
90
+
91
+ POLL_MS: 30_000, // loop delay
92
+ };
93
+
94
+ // ===== Alpaca setup =====
95
+ const alpaca = new Alpaca({
96
+ keyId: process.env.ALPACA_KEY_ID,
97
+ secretKey: process.env.ALPACA_SECRET_KEY,
98
+ paper: process.env.ALPACA_PAPER !== 'false',
99
+ rate_limit: true,
100
+ });
101
+
102
+ const ALPACA_REST_BASE =
103
+ process.env.ALPACA_PAPER === 'false'
104
+ ? 'https://api.alpaca.markets'
105
+ : 'https://paper-api.alpaca.markets';
106
+
107
+ const AUTH_HEADERS = {
108
+ 'APCA-API-KEY-ID': process.env.ALPACA_KEY_ID,
109
+ 'APCA-API-SECRET-KEY': process.env.ALPACA_SECRET_KEY,
110
+ };
111
+
112
+ function sleep(ms) {
113
+ return new Promise(res => setTimeout(res, ms));
114
+ }
115
+
116
+ // ===== Data + SMA helpers (Alpaca ETF bars) =====
117
+
118
+ async function fetchRecentBars(symbol) {
119
+ const end = new Date().toISOString();
120
+ const start = new Date(
121
+ Date.now() - CFG.BAR_LOOKBACK_DAYS * 24 * 60 * 60 * 1000
122
+ ).toISOString();
123
+
124
+ const bars = [];
125
+ const gen = alpaca.getBarsV2(symbol, {
126
+ start,
127
+ end,
128
+ timeframe: CFG.BAR_TIMEFRAME,
129
+ limit: CFG.BAR_LIMIT,
130
+ });
131
+
132
+ for await (const b of gen) {
133
+ bars.push(b);
134
+ }
135
+
136
+ bars.sort((a, b) => new Date(a.t) - new Date(b.t)); // ascending
137
+ return bars;
138
+ }
139
+
140
+ function smaForPeriod(bars, period, field = 'c') {
141
+ if (bars.length < period) return null;
142
+ let sum = 0;
143
+ for (let i = bars.length - period; i < bars.length; i++) {
144
+ sum += Number(bars[i][field]);
145
+ }
146
+ return sum / period;
147
+ }
148
+
149
+ function lastN(bars, n) {
150
+ if (bars.length <= n) return bars.slice();
151
+ return bars.slice(bars.length - n);
152
+ }
153
+
154
+ // ===== Multi-fib trend + retrace detection =====
155
+
156
+ /**
157
+ * Detect trend + retrace using a ladder of Fibonacci SMAs:
158
+ *
159
+ * 1. Compute SMA for all CFG.FIB_PERIODS.
160
+ * 2. For each triple [pShort, pMid, pLong] in CFG.FIB_TRIPLES (ascending):
161
+ * uptrend: SMA(pShort) > SMA(pMid) > SMA(pLong)
162
+ * downtrend: SMA(pShort) < SMA(pMid) < SMA(pLong)
163
+ * Keep the triple with the *largest pLong* that matches (longest “stack”).
164
+ * 3. Entry level is SMA(pShort) of that best triple (“next one” below the longer two).
165
+ * 4. Retrace condition:
166
+ * prev bar range crosses entry SMA
167
+ * last bar closes back in direction of trend.
168
+ *
169
+ * Returns:
170
+ * null OR
171
+ * { side: 'LONG' | 'SHORT', entryPeriod: number, triple: [pShort,pMid,pLong] }
172
+ */
173
+ function detectFibSignal(bars) {
174
+ if (bars.length < 200) return null; // sanity; you can relax this
175
+
176
+ const latest = bars[bars.length - 1];
177
+ const prev = bars[bars.length - 2];
178
+
179
+ // 1) SMA map
180
+ const smaMap = {};
181
+ for (const p of CFG.FIB_PERIODS) {
182
+ smaMap[p] = smaForPeriod(bars, p);
183
+ }
184
+
185
+ // 2) find best triple (largest pLong)
186
+ let best = null;
187
+
188
+ for (const triple of CFG.FIB_TRIPLES) {
189
+ const [pShort, pMid, pLong] = triple;
190
+ const sShort = smaMap[pShort];
191
+ const sMid = smaMap[pMid];
192
+ const sLong = smaMap[pLong];
193
+
194
+ if (sShort == null || sMid == null || sLong == null) continue;
195
+
196
+ const upTrend = sShort > sMid && sMid > sLong;
197
+ const downTrend = sShort < sMid && sMid < sLong;
198
+
199
+ if (!upTrend && !downTrend) continue;
200
+
201
+ if (
202
+ !best ||
203
+ pLong > best.triple[2] // prefer triple with longest long-period
204
+ ) {
205
+ best = {
206
+ side: upTrend ? 'LONG' : 'SHORT',
207
+ triple: triple,
208
+ entryPeriod: pShort, // “next one when the longer ones are above each other”
209
+ smaEntry: sShort,
210
+ };
211
+ }
212
+ }
213
+
214
+ if (!best) return null;
215
+
216
+ // 3) retrace condition to entry SMA
217
+ const entrySma = best.smaEntry;
218
+ const prevTouched =
219
+ Number(prev.l) <= entrySma && Number(prev.h) >= entrySma;
220
+
221
+ if (!prevTouched) return null;
222
+
223
+ if (best.side === 'LONG') {
224
+ if (Number(latest.c) > entrySma) return best;
225
+ } else {
226
+ if (Number(latest.c) < entrySma) return best;
227
+ }
228
+
229
+ return null;
230
+ }
231
+
232
+ // ===== Options hedge helpers (Alpaca) =====
233
+
234
+ async function pickClosestOption(symbol, type, underlyingPx) {
235
+ const url = `${ALPACA_REST_BASE}/v2/options/contracts`;
236
+
237
+ const res = await axios.get(url, {
238
+ headers: AUTH_HEADERS,
239
+ params: {
240
+ underlying_symbols: symbol,
241
+ type, // 'call' | 'put'
242
+ limit: 500,
243
+ },
244
+ });
245
+
246
+ const contracts = (res.data.option_contracts || []).filter(c => c.tradable);
247
+ if (!contracts.length) return null;
248
+
249
+ const today = new Date();
250
+
251
+ function dte(expStr) {
252
+ const d = new Date(expStr + 'T16:00:00Z');
253
+ return (d - today) / (24 * 60 * 60 * 1000);
254
+ }
255
+
256
+ const filtered = contracts.filter(c => {
257
+ const d = dte(c.expiration_date);
258
+ return d >= CFG.HEDGE_MIN_DTE && d <= CFG.HEDGE_MAX_DTE;
259
+ });
260
+
261
+ const pool = filtered.length ? filtered : contracts;
262
+
263
+ let best = null;
264
+ let bestDiff = Infinity;
265
+ for (const c of pool) {
266
+ const strike = Number(c.strike_price);
267
+ const diff = Math.abs(strike - underlyingPx);
268
+ if (diff < bestDiff) {
269
+ bestDiff = diff;
270
+ best = c;
271
+ }
272
+ }
273
+ return best || null;
274
+ }
275
+
276
+ // ===== TL order helpers (TODO: wire these to your ApiWrapper methods) =====
277
+
278
+ /**
279
+ * Place a TL market order via ApiWrapper.
280
+ *
281
+ * You *must* adapt this to your actual API. For example, if you have:
282
+ * api.spotMarketOrder({ market, side, amount })
283
+ * or
284
+ * api.placeOrder({ market, side, type: 'MARKET', size })
285
+ * then use that here.
286
+ */
287
+ async function tlMarketOrder(side, qty) {
288
+ console.log(`[TL] MARKET ${side} ${qty} ${CFG.TL_MARKET}`);
289
+
290
+ // TODO: replace this with your real call.
291
+ // Example placeholder:
292
+ if (typeof tlApi.placeOrder === 'function') {
293
+ return tlApi.placeOrder({
294
+ market: CFG.TL_MARKET,
295
+ side, // 'buy' | 'sell'
296
+ type: 'MARKET',
297
+ size: qty,
298
+ });
299
+ }
300
+
301
+ // If your wrapper uses a different signature, adjust accordingly:
302
+ // return tlApi.spotMarketOrder(CFG.TL_MARKET, side, qty);
303
+ }
304
+
305
+ // ===== Hedge management =====
306
+
307
+ async function closeHedgeIfAny() {
308
+ if (!currentHedgeSymbol) return;
309
+
310
+ try {
311
+ const positions = await alpaca.getPositions();
312
+ const hedgePos = positions.find(
313
+ p => p.symbol === currentHedgeSymbol && p.asset_class === 'option'
314
+ );
315
+ if (!hedgePos) {
316
+ currentHedgeSymbol = null;
317
+ return;
318
+ }
319
+
320
+ const qty = Number(hedgePos.qty);
321
+ if (!qty) {
322
+ currentHedgeSymbol = null;
323
+ return;
324
+ }
325
+
326
+ const side = hedgePos.side === 'long' ? 'sell' : 'buy';
327
+ console.log(`[EXIT HEDGE] ${currentHedgeSymbol} ${side} ${qty}`);
328
+
329
+ await alpaca.createOrder({
330
+ symbol: currentHedgeSymbol,
331
+ qty,
332
+ side,
333
+ type: 'market',
334
+ time_in_force: 'day',
335
+ });
336
+
337
+ currentHedgeSymbol = null;
338
+ } catch (e) {
339
+ console.log('Error closing hedge:', e.message || e);
340
+ }
341
+ }
342
+
343
+ // ===== Position & risk helpers =====
344
+
345
+ function bpsFrom(entry, current, side) {
346
+ if (side === 'long') {
347
+ return ((current - entry) / entry) * 10_000;
348
+ }
349
+ // short: profit when price goes down
350
+ return ((entry - current) / entry) * 10_000;
351
+ }
352
+
353
+ async function openTlAndMaybeHedge(signal, lastPrice) {
354
+ if (currentPosition) {
355
+ console.log('[SKIP] Already in TL position.');
356
+ return;
357
+ }
358
+
359
+ const shares = Math.max(1, Math.floor(CFG.BASE_NOTIONAL_USD / lastPrice));
360
+ const side = signal.side === 'LONG' ? 'buy' : 'sell';
361
+
362
+ console.log(
363
+ `[ENTRY] ${signal.side} TL ${CFG.TL_MARKET} ${shares} @ ETF≈${lastPrice.toFixed(
364
+ 2
365
+ )} using triple ${signal.triple.join('/')}`
366
+ );
367
+
368
+ await tlMarketOrder(side, shares);
369
+
370
+ currentPosition = {
371
+ side: signal.side === 'LONG' ? 'long' : 'short',
372
+ qty: shares,
373
+ entryPrice: lastPrice,
374
+ };
375
+
376
+ if (!CFG.USE_OPTION_HEDGE) {
377
+ console.log('[HEDGE] Disabled (USE_OPTION_HEDGE = false)');
378
+ return;
379
+ }
380
+
381
+ try {
382
+ const hedgeType = signal.side === 'LONG' ? 'put' : 'call';
383
+ const contract = await pickClosestOption(CFG.ETF_SYMBOL, hedgeType, lastPrice);
384
+ if (!contract) {
385
+ console.log('[HEDGE] No suitable option contract found.');
386
+ return;
387
+ }
388
+
389
+ const optSize = Number(contract.size || '100'); // contract multiplier
390
+ const optQty = Math.max(1, Math.round(shares / optSize));
391
+
392
+ console.log(
393
+ `[HEDGE] Buying ${optQty} ${contract.symbol} (${hedgeType}) near ${contract.strike_price}`
394
+ );
395
+
396
+ await alpaca.createOrder({
397
+ symbol: contract.symbol,
398
+ qty: optQty,
399
+ side: 'buy',
400
+ type: 'market',
401
+ time_in_force: 'day',
402
+ });
403
+
404
+ currentHedgeSymbol = contract.symbol;
405
+ } catch (e) {
406
+ console.log('Error creating hedge order:', e.message || e);
407
+ }
408
+ }
409
+
410
+ async function closeTlAndHedge() {
411
+ if (!currentPosition) return;
412
+
413
+ const exitSide = currentPosition.side === 'long' ? 'sell' : 'buy';
414
+
415
+ console.log(
416
+ `[EXIT] TL ${CFG.TL_MARKET} ${exitSide} ${currentPosition.qty}`
417
+ );
418
+ await tlMarketOrder(exitSide, currentPosition.qty);
419
+
420
+ await closeHedgeIfAny();
421
+ currentPosition = null;
422
+ }
423
+
424
+ // ===== Stop logic (last 5 bars + hard stop) =====
425
+
426
+ async function manageStops(bars) {
427
+ if (!currentPosition) return;
428
+
429
+ const last = bars[bars.length - 1];
430
+ const lastPrice = Number(last.c);
431
+ const entry = currentPosition.entryPrice;
432
+ const pnlBps = bpsFrom(entry, lastPrice, currentPosition.side);
433
+
434
+ // Hard stop when unhedged
435
+ if (!CFG.USE_OPTION_HEDGE && pnlBps <= -CFG.DEFAULT_STOP_BPS) {
436
+ console.log(
437
+ `[STOP] Hard stop hit at ${pnlBps.toFixed(
438
+ 2
439
+ )} bps (no hedge). Closing TL position.`
440
+ );
441
+ await closeTlAndHedge();
442
+ return;
443
+ }
444
+
445
+ // Trailing stop once sufficiently in profit
446
+ if (pnlBps >= CFG.PROFIT_TRAIL_TRIGGER_BPS) {
447
+ const last5 = lastN(bars, 5);
448
+ const lows = last5.map(b => Number(b.l));
449
+ const highs = last5.map(b => Number(b.h));
450
+
451
+ const trailLevelLong = Math.min(...lows);
452
+ const trailLevelShort = Math.max(...highs);
453
+
454
+ if (
455
+ currentPosition.side === 'long' &&
456
+ lastPrice <= trailLevelLong
457
+ ) {
458
+ console.log(
459
+ `[TRAIL] Long stop triggered @ ${lastPrice} <= ${trailLevelLong}`
460
+ );
461
+ await closeTlAndHedge();
462
+ return;
463
+ }
464
+
465
+ if (
466
+ currentPosition.side === 'short' &&
467
+ lastPrice >= trailLevelShort
468
+ ) {
469
+ console.log(
470
+ `[TRAIL] Short stop triggered @ ${lastPrice} >= ${trailLevelShort}`
471
+ );
472
+ await closeTlAndHedge();
473
+ return;
474
+ }
475
+ }
476
+ }
477
+
478
+ // ===== Main loop =====
479
+
480
+ async function mainLoop() {
481
+ console.log(
482
+ `Starting fib_sma_taker_tl for TL market=${CFG.TL_MARKET}, ETF=${CFG.ETF_SYMBOL}, timeframe=${CFG.BAR_TIMEFRAME}, hedge=${CFG.USE_OPTION_HEDGE ? 'ON' : 'OFF'}`
483
+ );
484
+
485
+ while (true) {
486
+ try {
487
+ const bars = await fetchRecentBars(CFG.ETF_SYMBOL);
488
+ if (!bars.length) {
489
+ console.log('[WARN] No bars returned, skipping loop.');
490
+ await sleep(CFG.POLL_MS);
491
+ continue;
492
+ }
493
+
494
+ const last = bars[bars.length - 1];
495
+ const lastPx = Number(last.c);
496
+
497
+ // 1) manage open TL position
498
+ await manageStops(bars);
499
+
500
+ // 2) consider new entry if flat
501
+ if (!currentPosition) {
502
+ const sig = detectFibSignal(bars);
503
+ if (sig) {
504
+ console.log(
505
+ `[SIGNAL] ${sig.side} @ close=${lastPx.toFixed(
506
+ 4
507
+ )} using triple ${sig.triple.join('/')}, entry SMA=${sig.entryPeriod}`
508
+ );
509
+ await openTlAndMaybeHedge(sig, lastPx);
510
+ } else {
511
+ console.log('[NO SIGNAL] Waiting…');
512
+ }
513
+ } else {
514
+ console.log(
515
+ `[IN POSITION] side=${currentPosition.side} qty=${currentPosition.qty} entry=${currentPosition.entryPrice.toFixed(
516
+ 4
517
+ )} etf_last=${lastPx.toFixed(4)}`
518
+ );
519
+ }
520
+ } catch (e) {
521
+ console.error('Loop error:', e.message || e);
522
+ }
523
+
524
+ await sleep(CFG.POLL_MS);
525
+ }
526
+ }
527
+
528
+ mainLoop().catch(e => {
529
+ console.error('Fatal error:', e.message || e);
530
+ process.exit(1);
531
+ });
package/decodeTest.js ADDED
@@ -0,0 +1,69 @@
1
+ const { Psbt } = require('bitcoinjs-lib');
2
+ const { ECPair } = require('bitcoinjs-lib');
3
+ const { payments } = require('bitcoinjs-lib');
4
+ const { Buffer } = require('buffer');
5
+
6
+ // Example PSBT object (this should be replaced with your actual PSBT data)
7
+ const psbtHex = "70736274ff0100c50200000002343025a90f60c20c72637d18c3dcf46dd31b7e1abe409982c1daa3f1753f6b060000000000ffffffffd7a4390df4a8811be886b1251343af95fe927567e3cb450ec42d797076e2b7960000000000ffffffff03b4db060000000000160014f94801072fc65f8c35db2363f75803f16a9da94b1027000000000000160014396d64761fb3feb3fcaf95bf1c21c8f36d680a7e0000000000000000226a20746c33302c302e3030346e796d386571756170712c302c3770732c302c312c30000000000001012b5415000000000000220020a30d39561520a26d39248fb24062bb1997df52e8b73a22828534e9d58ecd58ff220203f9967f334d7bcbe7bcefa41252ba488c3ceadf6da6c269bcada1ed0b9d600a5047304402205d097e72787447472f8b3edee44067c7ac313421725eb2b884fe01d7e6a3352a02200592f4809141b1c1fccaf900c351797ba8f8d7425298257967509e7f6668afc201010547522103f9967f334d7bcbe7bcefa41252ba488c3ceadf6da6c269bcada1ed0b9d600a5021035d0c4cf2ea856bef98dba896f7e82bd9d80cedd08d117253e9ce225079f72b4b52ae0001011f90f0060000000000160014f94801072fc65f8c35db2363f75803f16a9da94b00000000"
8
+ // Decode the PSBT
9
+ const psbt = Psbt.fromHex(psbtHex);
10
+
11
+ // Check all inputs and their validity
12
+ psbt.data.inputs.forEach((input, index) => {
13
+ console.log(`Analyzing input ${index + 1} - TXID: ${input.txid}`);
14
+
15
+ // Check witness script
16
+ if (input.witnessUtxo && input.witnessUtxo.script) {
17
+ const witnessScript = input.witnessUtxo.script;
18
+ console.log(`Witness script for input ${index + 1}: `, witnessScript.toString('hex'));
19
+
20
+ // If it's multisig, it should match the expected structure
21
+ if (input.witnessScript) {
22
+ const isMultisig = witnessScript[0] === 0x52; // 0x52 is the OP_CHECKMULTISIG opcode
23
+ if (isMultisig) {
24
+ console.log("This input is a multisig input.");
25
+ // Decode and check public keys in multisig (optional)
26
+ } else {
27
+ console.log("This input is not a multisig input.");
28
+ }
29
+ }
30
+ }
31
+
32
+ // Verify the signatures
33
+ if (input.partialSig) {
34
+ input.partialSig.forEach((sigData, sigIndex) => {
35
+ const pubkey = sigData.pubkey.toString('hex');
36
+ const signature = sigData.signature.toString('hex');
37
+ console.log(`Signature ${sigIndex + 1} for input ${index + 1}:`);
38
+ console.log(`Pubkey: ${pubkey}`);
39
+ console.log(`Signature: ${signature}`);
40
+ });
41
+ }
42
+ });
43
+
44
+ // Check all outputs
45
+ psbt.data.outputs.forEach((output, index) => {
46
+ console.log(`Analyzing output ${index + 1} - Value: ${output.value}`);
47
+
48
+ const script = output.script;
49
+ console.log(`Output scriptPubKey for output ${index + 1}: `, script.toString('hex'));
50
+
51
+ // Check if it's a P2WPKH or P2PKH output
52
+ const p2wpkh = payments.p2wpkh({ output: script });
53
+ const p2pkh = payments.p2pkh({ output: script });
54
+
55
+ if (p2wpkh) {
56
+ console.log("This is a P2WPKH output.");
57
+ } else if (p2pkh) {
58
+ console.log("This is a P2PKH output.");
59
+ } else {
60
+ console.log("This is an unknown output type.");
61
+ }
62
+ });
63
+
64
+ // Check that the PSBT is finalized (signed)
65
+ if (psbt.finalized) {
66
+ console.log("PSBT is finalized (signed).");
67
+ } else {
68
+ console.log("PSBT is not finalized. It may still need signing.");
69
+ }